diff --git a/asset-manifest.json b/asset-manifest.json index 5a12663..3ca87b6 100644 --- a/asset-manifest.json +++ b/asset-manifest.json @@ -1,8 +1,8 @@ { "files": { "main.css": "/webminidisc/static/css/main.0b990f46.chunk.css", - "main.js": "/webminidisc/static/js/main.79696204.chunk.js", - "main.js.map": "/webminidisc/static/js/main.79696204.chunk.js.map", + "main.js": "/webminidisc/static/js/main.a222d332.chunk.js", + "main.js.map": "/webminidisc/static/js/main.a222d332.chunk.js.map", "runtime-main.js": "/webminidisc/static/js/runtime-main.114d47b9.js", "runtime-main.js.map": "/webminidisc/static/js/runtime-main.114d47b9.js.map", "static/js/2.7f5ae350.chunk.js": "/webminidisc/static/js/2.7f5ae350.chunk.js", @@ -14,7 +14,7 @@ "ff3100a0019baa5b3604.worker.js.LICENSE.txt": "/webminidisc/ff3100a0019baa5b3604.worker.js.LICENSE.txt", "ff3100a0019baa5b3604.worker.js.map": "/webminidisc/ff3100a0019baa5b3604.worker.js.map", "index.html": "/webminidisc/index.html", - "precache-manifest.4f525d539c46c181a0d761bf3e7c30a3.js": "/webminidisc/precache-manifest.4f525d539c46c181a0d761bf3e7c30a3.js", + "precache-manifest.09c5a08892fa12a801990b476996a98f.js": "/webminidisc/precache-manifest.09c5a08892fa12a801990b476996a98f.js", "service-worker.js": "/webminidisc/service-worker.js", "static/css/main.0b990f46.chunk.css.map": "/webminidisc/static/css/main.0b990f46.chunk.css.map", "static/js/2.7f5ae350.chunk.js.LICENSE.txt": "/webminidisc/static/js/2.7f5ae350.chunk.js.LICENSE.txt", @@ -24,6 +24,6 @@ "static/js/runtime-main.114d47b9.js", "static/js/2.7f5ae350.chunk.js", "static/css/main.0b990f46.chunk.css", - "static/js/main.79696204.chunk.js" + "static/js/main.a222d332.chunk.js" ] } \ No newline at end of file diff --git a/extra-service-worker.js b/extra-service-worker.js new file mode 100644 index 0000000..0ef59b9 --- /dev/null +++ b/extra-service-worker.js @@ -0,0 +1,17 @@ +// List of extra files to be precached for offline use. +// WARNING: don't forget to update the revision before deploy +var revision = "6"; +self.__precacheManifest = (self.__precacheManifest || []).concat([ + { + "revision": revision, + "url": "/webminidisc/atracdenc.js" + }, + { + "revision": revision, + "url": "/webminidisc/worker.min.js" + }, + { + "revision": revision, + "url": "/webminidisc/ffmpeg-core.js" + }, +]); diff --git a/final-service-worker.js b/final-service-worker.js new file mode 100644 index 0000000..86d11a5 --- /dev/null +++ b/final-service-worker.js @@ -0,0 +1,56 @@ +// List of extra files to be precached for offline use. +// WARNING: don't forget to update the revision before deploy +var revision = "6"; +self.__precacheManifest = (self.__precacheManifest || []).concat([ + { + "revision": revision, + "url": "/webminidisc/atracdenc.js" + }, + { + "revision": revision, + "url": "/webminidisc/worker.min.js" + }, + { + "revision": revision, + "url": "/webminidisc/ffmpeg-core.js" + }, +]); +/** + * Welcome to your Workbox-powered service worker! + * + * You'll need to register this file in your web app and you should + * disable HTTP caching for this file too. + * See https://goo.gl/nhQhGp + * + * The rest of the code is auto-generated. Please don't update this file + * directly; instead, make changes to your Workbox build configuration + * and re-run your build process. + * See https://goo.gl/2aRDsh + */ + +importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); + +importScripts( + "/webminidisc/precache-manifest.09c5a08892fa12a801990b476996a98f.js" +); + +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') { + self.skipWaiting(); + } +}); + +workbox.core.clientsClaim(); + +/** + * The workboxSW.precacheAndRoute() method efficiently caches and responds to + * requests for URLs in the manifest. + * See https://goo.gl/S9QRab + */ +self.__precacheManifest = [].concat(self.__precacheManifest || []); +workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); + +workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/webminidisc/index.html"), { + + blacklist: [/^\/_/,/\/[^/?]+\.[^/]+$/], +}); diff --git a/index.html b/index.html index 1dfd79a..27751ab 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -Web MiniDisc - Brings NetMD Devices to the Web
\ No newline at end of file +Web MiniDisc - Brings NetMD Devices to the Web
\ No newline at end of file diff --git a/precache-manifest.4f525d539c46c181a0d761bf3e7c30a3.js b/precache-manifest.09c5a08892fa12a801990b476996a98f.js similarity index 85% rename from precache-manifest.4f525d539c46c181a0d761bf3e7c30a3.js rename to precache-manifest.09c5a08892fa12a801990b476996a98f.js index 29139e2..56ce3e9 100644 --- a/precache-manifest.4f525d539c46c181a0d761bf3e7c30a3.js +++ b/precache-manifest.09c5a08892fa12a801990b476996a98f.js @@ -16,11 +16,11 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "/webminidisc/ff3100a0019baa5b3604.worker.js.LICENSE.txt" }, { - "revision": "34ffc4245f076388f3453be5f83e7e0f", + "revision": "8c2179887b6d4b1f4ee8b643a6ed29bc", "url": "/webminidisc/index.html" }, { - "revision": "5d2cde985b937e7ff0e5", + "revision": "b32861e27ed3e8d3a64a", "url": "/webminidisc/static/css/main.0b990f46.chunk.css" }, { @@ -32,8 +32,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "/webminidisc/static/js/2.7f5ae350.chunk.js.LICENSE.txt" }, { - "revision": "5d2cde985b937e7ff0e5", - "url": "/webminidisc/static/js/main.79696204.chunk.js" + "revision": "b32861e27ed3e8d3a64a", + "url": "/webminidisc/static/js/main.a222d332.chunk.js" }, { "revision": "b873df5f5158f06b4f7b", diff --git a/service-worker.js b/service-worker.js index 9728d75..bdf001a 100644 --- a/service-worker.js +++ b/service-worker.js @@ -14,7 +14,7 @@ importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); importScripts( - "/webminidisc/precache-manifest.4f525d539c46c181a0d761bf3e7c30a3.js" + "/webminidisc/precache-manifest.09c5a08892fa12a801990b476996a98f.js" ); self.addEventListener('message', (event) => { diff --git a/static/js/main.79696204.chunk.js.map b/static/js/main.79696204.chunk.js.map deleted file mode 100644 index b6d0dbd..0000000 --- a/static/js/main.79696204.chunk.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["images/chrome-icon.svg","webpack:///./src/services/atracdenc-worker.ts?dc3c","serviceWorker.ts","services/netmd.ts","services/registry.ts","redux/upload-dialog-feature.ts","redux/rename-dialog-feature.ts","redux/error-dialog-feature.ts","redux/convert-dialog-feature.ts","utils.ts","redux/app-feature.ts","redux/main-feature.ts","redux/store.ts","redux/actions.ts","services/atracdenc-worker.ts","components/about-dialog.tsx","components/topmenu.tsx","components/welcome.tsx","components/rename-dialog.tsx","components/upload-dialog.tsx","components/error-dialog.tsx","components/convert-dialog.tsx","components/main.tsx","components/app.tsx","services/audio-export.ts","index.tsx"],"names":["module","exports","Worker","isLocalhost","Boolean","window","location","hostname","match","registerValidSW","swUrl","config","navigator","serviceWorker","register","then","registration","onupdatefound","installingWorker","installing","onstatechange","console","log","state","controller","onUpdate","onSuccess","update","catch","error","require","NetMDUSBService","netmdInterface","openNewDevice","usb","iface","this","openPairedDevice","listContent","netMd","getDeviceName","finalize","index","newTitle","setTrackTitle","eraseTrack","eraseDisc","title","data","format","progressCallback","updateProgress","written","encrypted","total","byteLength","w","webWorkerAsyncPacketIterator","makeGetAsyncPacketIteratorOnWorkerThread","encryptedBytes","mdTrack","MDTrack","download","writtenBytes","ServiceRegistry","slice","createSlice","name","initialState","visible","writtenProgress","encryptedProgress","totalProgress","trackTotal","trackConverting","trackCurrent","titleCurrent","titleConverting","reducers","setVisible","action","payload","setWriteProgress","setTrackProgress","current","converting","reducer","actions","enableBatching","setCurrentName","setIndex","setErrorMessage","setFormat","useShallowEqualSelector","selector","useSelector","shallowEqual","getPublicPathFor","script","process","mainView","loading","pairingFailed","pairingMessage","browserSupported","darkMode","key","defaultValue","res","localStorage","getItem","JSON","parse","e","loadPreference","aboutDialogVisible","setState","setLoading","setPairingFailed","setPairingMessage","setBrowserSupported","setDarkMode","value","setItem","stringify","showAboutDialog","disc","deviceName","setDisc","setDeviceName","store","configureStore","renameDialog","uploadDialog","errorDialog","convertDialog","appState","main","middleware","getDefaultMiddleware","dispatch","a","appStateActions","serviceRegistry","netmdService","batchActions","mainActions","WireformatDict","SP","Wireformat","pcm","LP2","lp2","LP105","l105kbps","LP4","lp4","Module","Transition","React","forwardRef","props","ref","Slide","direction","AboutDialog","useDispatch","Dialog","open","maxWidth","fullWidth","TransitionComponent","aria-labelledby","DialogTitle","id","DialogContent","DialogContentText","Link","rel","href","target","DialogActions","Button","onClick","appActions","TopMenu","useState","menuAnchorEl","setMenuAnchorEl","menuOpen","handleMenuClose","menuItems","push","MenuItem","wipeDisc","Fragment","IconButton","aria-label","aria-controls","aria-haspopup","event","currentTarget","Menu","anchorEl","keepMounted","onClose","useStyles","makeStyles","theme","position","flex","display","justifyContent","flexDirection","alignItems","button","marginTop","spacing","minWidth","chromeLogo","width","height","why","alignSelf","headBox","Welcome","classes","toLowerCase","showWhyUnsupported","setWhyUnsupported","Box","className","Typography","component","variant","align","color","getState","audioExportService","init","connect","pair","message","FormControl","style","visibility","FormHelperText","preventDefault","alt","src","ChromeIconPath","RenameDialog","renameDialogVisible","renameDialogTitle","renameDialogIndex","handleCancelRename","renameDialogActions","handleDoRename","newName","renameTrack","TextField","autoFocus","label","type","onKeyDown","onChange","progressPerc","progressBar","uploadLabel","UploadDialog","progressValue","Math","floor","bufferValue","convertedValue","aria-describedby","LinearProgress","valueBuffer","ErrorDialog","errorDialogActions","container","formControl","ConvertDialog","handleClose","convertDialogActions","InputLabel","Select","labelId","ev","input","Input","files","wireformat","uploadDialogActions","updateProgressCallback","trackUpdate","length","updateTrack","conversionIterator","convertNext","i","f","converted","Promise","resolve","reject","prepare","export","file","errorMessage","j","item","upload","actionToDispatch","concat","errorDialogAction","convertAndUpload","add","bottom","right","overflowY","marginBottom","marginLeft","marginRight","outline","toolbar","breakpoints","up","toolbarLabel","toolbarHighlight","palette","secondary","backgroundColor","lighten","light","text","primary","dark","formatBadge","BadgeImpl","badge","colorPrimary","border","background","paper","padding","titleCell","overflow","textOverflow","backdrop","zIndex","drawer","EncodingName","Encoding","sp","Main","selected","setSelected","selectedCount","useEffect","uploadedFiles","setUploadedFiles","onDrop","useCallback","acceptedFiles","rejectedFiles","useDropzone","accept","noClick","getRootProps","getInputProps","isDragActive","tracks","groups","group","track","encoding","duration","formatTimeFromFrames","handleRenameDoubleClick","selectedIndex","currentName","getTracks","find","left","Toolbar","clsx","Checkbox","indeterminate","checked","map","t","inputProps","Tooltip","indexes","sort","reverse","deleteTrack","disabled","Table","size","TableHead","TableRow","TableCell","TableBody","hover","includes","onDoubleClick","filter","Backdrop","Fab","layout","copyright","minidiscLogo","darkTheme","createMuiTheme","contrastText","lightTheme","App","ThemeProvider","CssBaseline","Paper","undefined","Date","getFullYear","data-via","data-hashtags","data-dnt","data-show-count","CircularProgress","AtracdencProcess","worker","messageCallback","onmessage","handleMessage","bind","postMessage","bitrate","eventData","result","WorkerGlobalScope","self","others","importScripts","m","setLogger","msg","stream","dataArray","Uint8Array","FS","writeFile","callMain","fileStat","stat","tmp","outAt3FileStream","read","close","buffer","AtracdencWorker","FFMpegAudioExportService","ffmpegProcess","atracdencProcess","loglines","inFileName","outFileNameNoExt","setLogging","createWorker","logger","corePath","workerPath","load","ext","split","Error","write","transcode","audioFormatRegex","inputFormatRegex","line","outFileName","encode","addEventListener","returnValue","ondisconnect","ReactDOM","render","document","getElementById","URL","origin","fetch","headers","response","contentType","get","status","indexOf","ready","unregister","reload","checkValidServiceWorker"],"mappings":"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","file":"static/js/main.79696204.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/chrome-icon.f3b6c54c.svg\";","module.exports = function() {\n return new Worker(__webpack_public_path__ + \"cc43d050d6e858b79f86.worker.js\");\n};","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(/^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/custom-service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' + 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n console.log('state change', installingWorker.state);\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n registration.update(); // Check for new version everytime we load the page\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' },\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log('No internet connection found. App is running in offline mode.');\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import { openNewDevice, NetMDInterface, Disc, listContent, openPairedDevice, Wireformat, MDTrack, download } from 'netmd-js';\nimport { makeGetAsyncPacketIteratorOnWorkerThread } from 'netmd-js/dist/web-encrypt-worker';\n\nconst Worker = require('worker-loader!netmd-js/dist/web-encrypt-worker.js'); // eslint-disable-line import/no-webpack-loader-syntax\n\nexport interface NetMDService {\n pair(): Promise;\n connect(): Promise;\n listContent(): Promise;\n getDeviceName(): Promise;\n finalize(): Promise;\n renameTrack(index: number, newTitle: string): Promise;\n deleteTrack(index: number): Promise;\n wipeDisc(): Promise;\n upload(\n title: string,\n data: ArrayBuffer,\n format: Wireformat,\n progressCallback: (progress: { written: number; encrypted: number; total: number }) => void\n ): Promise;\n}\n\nexport class NetMDUSBService implements NetMDService {\n private netmdInterface?: NetMDInterface;\n\n async pair() {\n let iface = await openNewDevice(navigator.usb);\n if (iface === null) {\n return false;\n }\n this.netmdInterface = iface;\n return true;\n }\n\n async connect() {\n let iface = await openPairedDevice(navigator.usb);\n if (iface === null) {\n return false;\n }\n this.netmdInterface = iface;\n return true;\n }\n\n async listContent() {\n return await listContent(this.netmdInterface!);\n }\n\n async getDeviceName() {\n return await this.netmdInterface!.netMd.getDeviceName();\n }\n\n async finalize() {\n await this.netmdInterface!.netMd.finalize();\n }\n\n async renameTrack(index: number, newTitle: string) {\n await this.netmdInterface!.setTrackTitle(index, newTitle);\n }\n\n async deleteTrack(index: number) {\n await this.netmdInterface!.eraseTrack(index);\n }\n\n async wipeDisc() {\n await this.netmdInterface!.eraseDisc();\n }\n\n async upload(\n title: string,\n data: ArrayBuffer,\n format: Wireformat,\n progressCallback: (progress: { written: number; encrypted: number; total: number }) => void\n ) {\n let total = data.byteLength;\n let written = 0;\n let encrypted = 0;\n function updateProgress() {\n progressCallback({ written, encrypted, total });\n }\n\n let w = new Worker();\n\n let webWorkerAsyncPacketIterator = makeGetAsyncPacketIteratorOnWorkerThread(w, ({ encryptedBytes }) => {\n encrypted = encryptedBytes;\n updateProgress();\n });\n\n let mdTrack = new MDTrack(title, format, data, 0x80000, webWorkerAsyncPacketIterator);\n\n await download(this.netmdInterface!, mdTrack, ({ writtenBytes }) => {\n written = writtenBytes;\n updateProgress();\n });\n }\n}\n","import { NetMDService } from './netmd';\nimport { AudioExportService } from './audio-export';\n\ninterface ServiceRegistry {\n netmdService?: NetMDService;\n audioExportService?: AudioExportService;\n}\n\nconst ServiceRegistry: ServiceRegistry = {};\n\nexport default ServiceRegistry;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface LoadingDialogState {\n visible: boolean;\n writtenProgress: number;\n encryptedProgress: number;\n totalProgress: number;\n\n trackTotal: number;\n trackConverting: number;\n trackCurrent: number;\n\n titleCurrent: string;\n titleConverting: string;\n}\n\nconst initialState: LoadingDialogState = {\n visible: false,\n // Current Track Upload\n writtenProgress: 0,\n encryptedProgress: 0,\n totalProgress: 1,\n\n // Tracks done\n trackTotal: 1,\n trackConverting: 0,\n trackCurrent: 0,\n titleCurrent: '',\n titleConverting: '',\n};\n\nexport const slice = createSlice({\n name: 'uploadDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setWriteProgress: (state, action: PayloadAction<{ written: number; encrypted: number; total: number }>) => {\n state.encryptedProgress = action.payload.encrypted;\n state.writtenProgress = action.payload.written;\n state.totalProgress = action.payload.total;\n },\n setTrackProgress: (\n state,\n action: PayloadAction<{ total: number; current: number; converting: number; titleCurrent: string; titleConverting: string }>\n ) => {\n state.trackTotal = action.payload.total;\n state.trackCurrent = action.payload.current;\n state.trackConverting = action.payload.converting;\n state.titleCurrent = action.payload.titleCurrent;\n state.titleConverting = action.payload.titleConverting;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface RenameDialogState {\n visible: boolean;\n title: string;\n index: number;\n}\n\nconst initialState: RenameDialogState = {\n visible: false,\n title: '',\n index: -1,\n};\n\nexport const slice = createSlice({\n name: 'renameDialog',\n initialState,\n reducers: {\n setVisible: (state: RenameDialogState, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setCurrentName: (state: RenameDialogState, action: PayloadAction) => {\n state.title = action.payload;\n },\n setIndex: (state: RenameDialogState, action: PayloadAction) => {\n state.index = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface ErrorDialogState {\n visible: boolean;\n error: string;\n}\n\nconst initialState: ErrorDialogState = {\n visible: false,\n error: ``,\n};\n\nconst slice = createSlice({\n name: 'errorDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setErrorMessage: (state, action: PayloadAction) => {\n state.error = `${action.payload}`;\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface ConvertDialogFeature {\n visible: boolean;\n format: string;\n}\n\nconst initialState: ConvertDialogFeature = {\n visible: false,\n format: `LP2`,\n};\n\nconst slice = createSlice({\n name: 'convertDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setFormat: (state, action: PayloadAction) => {\n state.format = action.payload;\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { useSelector, shallowEqual } from 'react-redux';\nimport { RootState } from './redux/store';\n\nexport function sleep(ms: number) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\nexport function useShallowEqualSelector(selector: (state: TState) => TSelected): TSelected {\n return useSelector(selector, shallowEqual);\n}\n\nexport function hasWebUSB(): boolean {\n return !!navigator.usb;\n}\n\nexport function getWebUSB(): USB {\n return navigator.usb;\n}\n\nexport function debugEnabled() {\n return process.env.NODE_ENV === 'development';\n}\n\nexport function getPublicPathFor(script: string) {\n return `${process.env.PUBLIC_URL}/${script}`;\n}\n\nexport function savePreference(key: string, value: unknown) {\n localStorage.setItem(key, JSON.stringify(value));\n}\n\nexport function loadPreference(key: string, defaultValue: T): T {\n let res = localStorage.getItem(key);\n if (res === null) {\n return defaultValue;\n } else {\n try {\n return JSON.parse(res) as T;\n } catch (e) {\n return defaultValue;\n }\n }\n}\n\ndeclare let process: any;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\nimport { savePreference, loadPreference } from '../utils';\n\ntype Views = 'WELCOME' | 'MAIN';\n\nexport interface AppState {\n mainView: Views;\n loading: boolean;\n pairingFailed: boolean;\n pairingMessage: string;\n browserSupported: boolean;\n darkMode: boolean;\n aboutDialogVisible: boolean;\n}\n\nconst initialState: AppState = {\n mainView: 'WELCOME',\n loading: false,\n pairingFailed: false,\n pairingMessage: ``,\n browserSupported: true,\n darkMode: loadPreference('darkMode', false),\n aboutDialogVisible: false,\n};\n\nexport const slice = createSlice({\n name: 'app',\n initialState,\n reducers: {\n setState: (state, action: PayloadAction) => {\n state.mainView = action.payload;\n },\n setLoading: (state, action: PayloadAction) => {\n state.loading = action.payload;\n },\n setPairingFailed: (state, action: PayloadAction) => {\n state.pairingFailed = action.payload;\n },\n setPairingMessage: (state, action: PayloadAction) => {\n state.pairingMessage = action.payload;\n },\n setBrowserSupported: (state, action: PayloadAction) => {\n state.browserSupported = action.payload;\n },\n setDarkMode: (state, action: PayloadAction) => {\n state.darkMode = action.payload;\n savePreference('darkMode', state.darkMode);\n },\n showAboutDialog: (state, action: PayloadAction) => {\n state.aboutDialogVisible = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { Disc } from 'netmd-js';\nimport { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface MainState {\n disc: Disc | null;\n deviceName: string;\n}\n\nconst initialState: MainState = {\n disc: null,\n deviceName: '',\n};\n\nexport const slice = createSlice({\n name: 'main',\n initialState,\n reducers: {\n setDisc: (state, action: PayloadAction) => {\n state.disc = action.payload;\n },\n setDeviceName: (state, action: PayloadAction) => {\n state.deviceName = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';\nimport uploadDialog from './upload-dialog-feature';\nimport renameDialog from './rename-dialog-feature';\nimport errorDialog from './error-dialog-feature';\nimport convertDialog from './convert-dialog-feature';\nimport appState from './app-feature';\nimport main from './main-feature';\n\nexport const store = configureStore({\n reducer: {\n renameDialog,\n uploadDialog,\n errorDialog,\n convertDialog,\n appState,\n main,\n },\n middleware: [...getDefaultMiddleware()],\n});\n\nexport type RootState = ReturnType;\nexport type AppDispatch = typeof store.dispatch;\n","import { batchActions } from 'redux-batched-actions';\nimport { AppDispatch, RootState } from './store';\nimport { actions as uploadDialogActions } from './upload-dialog-feature';\nimport { actions as renameDialogActions } from './rename-dialog-feature';\nimport { actions as errorDialogAction } from './error-dialog-feature';\nimport { actions as appStateActions } from './app-feature';\nimport { actions as mainActions } from './main-feature';\nimport serviceRegistry from '../services/registry';\nimport { Wireformat } from 'netmd-js';\nimport { AnyAction } from '@reduxjs/toolkit';\n\nexport function pair() {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n dispatch(appStateActions.setPairingFailed(false));\n\n await serviceRegistry.audioExportService!.init();\n\n try {\n let connected = await serviceRegistry.netmdService!.connect();\n if (connected) {\n dispatch(appStateActions.setState('MAIN'));\n return;\n }\n } catch (err) {\n console.error(err);\n // In case of error, just log and try to pair\n }\n\n try {\n let paired = await serviceRegistry.netmdService!.pair();\n if (paired) {\n dispatch(appStateActions.setState('MAIN'));\n return;\n }\n dispatch(batchActions([appStateActions.setPairingMessage(`Connection Failed`), appStateActions.setPairingFailed(true)]));\n } catch (err) {\n console.error(err);\n let message = (err as Error).message;\n dispatch(batchActions([appStateActions.setPairingMessage(message), appStateActions.setPairingFailed(true)]));\n }\n };\n}\n\nexport function listContent() {\n return async function(dispatch: AppDispatch) {\n // Issue loading\n dispatch(appStateActions.setLoading(true));\n let disc = await serviceRegistry.netmdService!.listContent();\n let deviceName = await serviceRegistry.netmdService!.getDeviceName();\n dispatch(batchActions([mainActions.setDisc(disc), mainActions.setDeviceName(deviceName), appStateActions.setLoading(false)]));\n };\n}\n\nexport function renameTrack({ index, newName }: { index: number; newName: string }) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n await netmdService!.renameTrack(index, newName);\n dispatch(renameDialogActions.setVisible(false));\n listContent()(dispatch);\n };\n}\n\nexport function deleteTracks(indexes: number[]) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n dispatch(appStateActions.setLoading(true));\n indexes = indexes.sort();\n indexes.reverse();\n for (let index of indexes) {\n await netmdService!.deleteTrack(index);\n }\n listContent()(dispatch);\n };\n}\n\nexport function wipeDisc() {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n dispatch(appStateActions.setLoading(true));\n await netmdService!.wipeDisc();\n listContent()(dispatch);\n };\n}\n\nexport const WireformatDict: { [k: string]: Wireformat } = {\n SP: Wireformat.pcm,\n LP2: Wireformat.lp2,\n LP105: Wireformat.l105kbps,\n LP4: Wireformat.lp4,\n};\n\nexport function convertAndUpload(files: File[], format: string) {\n return async function(dispatch: AppDispatch, getState: (state: RootState) => void) {\n const { audioExportService, netmdService } = serviceRegistry;\n const wireformat = WireformatDict[format];\n\n dispatch(uploadDialogActions.setVisible(true));\n\n const updateProgressCallback = ({ written, encrypted, total }: { written: number; encrypted: number; total: number }) => {\n dispatch(uploadDialogActions.setWriteProgress({ written, encrypted, total }));\n };\n\n let trackUpdate: {\n current: number;\n converting: number;\n total: number;\n titleCurrent: string;\n titleConverting: string;\n } = {\n current: 0,\n converting: 0,\n total: files.length,\n titleCurrent: '',\n titleConverting: '',\n };\n const updateTrack = () => {\n dispatch(uploadDialogActions.setTrackProgress(trackUpdate));\n };\n\n let conversionIterator = async function*(files: File[]) {\n let converted: Promise<{ file: File; data: ArrayBuffer }>[] = [];\n\n let i = 0;\n function convertNext() {\n if (i === files.length) {\n trackUpdate.converting = i;\n trackUpdate.titleConverting = ``;\n updateTrack();\n return;\n }\n\n let f = files[i];\n trackUpdate.converting = i;\n trackUpdate.titleConverting = f.name;\n updateTrack();\n i++;\n\n converted.push(\n new Promise(async (resolve, reject) => {\n let data: ArrayBuffer;\n try {\n await audioExportService!.prepare(f);\n data = await audioExportService!.export({ format });\n convertNext();\n resolve({ file: f, data: data });\n } catch (err) {\n error = err;\n errorMessage = `${f.name}: Unsupported or unrecognized format`;\n reject(err);\n }\n })\n );\n }\n convertNext();\n\n let j = 0;\n while (j < converted.length) {\n yield await converted[j];\n j++;\n }\n };\n\n let error: any;\n let errorMessage = ``;\n let i = 1;\n for await (let item of conversionIterator(files)) {\n const { file, data } = item;\n\n trackUpdate.current = i++;\n trackUpdate.titleCurrent = file.name;\n updateTrack();\n updateProgressCallback({ written: 0, encrypted: 0, total: 100 });\n try {\n await netmdService?.upload(file.name, data, wireformat, updateProgressCallback);\n } catch (err) {\n error = err;\n errorMessage = `${file.name}: Error uploading to device`;\n break;\n }\n }\n\n let actionToDispatch: AnyAction[] = [uploadDialogActions.setVisible(false)];\n\n if (error) {\n console.error(error);\n actionToDispatch = actionToDispatch.concat([\n errorDialogAction.setVisible(true),\n errorDialogAction.setErrorMessage(errorMessage),\n ]);\n }\n\n dispatch(batchActions(actionToDispatch));\n listContent()(dispatch);\n };\n}\n","/* eslint no-restricted-globals: 0 */\nimport { getPublicPathFor } from '../utils';\nexport class AtracdencProcess {\n private messageCallback?: (ev: MessageEvent) => void;\n\n constructor(public worker: Worker) {\n worker.onmessage = this.handleMessage.bind(this);\n }\n\n async init() {\n await new Promise(resolve => {\n this.messageCallback = resolve;\n this.worker.postMessage({ action: 'init' });\n });\n }\n\n async encode(data: ArrayBuffer, bitrate: string) {\n let eventData = await new Promise(resolve => {\n this.messageCallback = resolve;\n this.worker.postMessage({ action: 'encode', bitrate, data }, [data]);\n });\n return eventData.data.result as Uint8Array;\n }\n\n handleMessage(ev: MessageEvent) {\n this.messageCallback!(ev);\n this.messageCallback = undefined;\n }\n}\n\nif (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {\n // Worker\n let Module: any;\n onmessage = async (ev: MessageEvent) => {\n const { action, ...others } = ev.data;\n if (action === 'init') {\n self.importScripts(getPublicPathFor(`atracdenc.js`));\n (self as any).Module().then((m: any) => {\n Module = m;\n self.postMessage({ action: 'init' });\n Module.setLogger && Module.setLogger((msg: string, stream: string) => console.log(`${stream}: ${msg}`));\n });\n } else if (action === 'encode') {\n const { bitrate, data } = others;\n const inWavFile = `inWavFile.wav`;\n const outAt3File = `outAt3File.aea`;\n const dataArray = new Uint8Array(data);\n Module.FS.writeFile(`${inWavFile}`, dataArray);\n Module.callMain([`-e`, `atrac3`, `-i`, inWavFile, `-o`, outAt3File, `--bitrate`, bitrate]);\n\n // Read file and trim header (96 bytes)\n let fileStat = Module.FS.stat(outAt3File);\n let size = fileStat.size;\n let tmp = new Uint8Array(size - 96);\n let outAt3FileStream = Module.FS.open(outAt3File, 'r');\n Module.FS.read(outAt3FileStream, tmp, 0, tmp.length, 96);\n Module.FS.close(outAt3FileStream);\n\n let result = tmp.buffer;\n\n self.postMessage(\n {\n action: 'encode',\n result,\n },\n [result]\n );\n self.close();\n }\n };\n} else {\n // Main\n}\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as appActions } from '../redux/app-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport Link from '@material-ui/core/Link';\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nexport const AboutDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let visible = useShallowEqualSelector(state => state.appState.aboutDialogVisible);\n\n const handleClose = () => {\n dispatch(appActions.showAboutDialog(false));\n };\n\n return (\n \n About Web MiniDisc\n \n Web MiniDisc has been made possible by\n
    \n
  • \n \n FFmpeg\n {' '}\n and{' '}\n \n ffmpegjs\n \n , to read your audio files (wav, mp3, ogg, mp4, etc...).\n
  • \n
  • \n \n Atracdenc\n \n , to support atrac3 encoding (lp2, lp4 audio formats).\n
  • \n
  • \n \n Emscripten\n \n , to run both FFmpeg and Atracdenc in the browser.\n
  • \n
  • \n \n netmd-js\n \n , to send commands to NetMD devices using Javascript.\n
  • \n
  • \n \n linux-minidisc\n \n , to make the netmd-js project possible.\n
  • \n
  • \n \n material-ui\n \n , to build the user interface.\n
  • \n
\n Attribution\n
    \n
  • \n MiniDisc logo from{' '}\n \n https://en.wikipedia.org/wiki/MiniDisc\n \n
  • \n
  • \n MiniDisc icon from{' '}\n \n http://fav.me/d7u3g3g\n \n
  • \n
\n
\n \n \n \n \n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MoreVertIcon from '@material-ui/icons/MoreVert';\n\nimport { wipeDisc, listContent } from '../redux/actions';\nimport { actions as appActions } from '../redux/app-feature';\nimport { useShallowEqualSelector } from '../utils';\nimport Link from '@material-ui/core/Link';\n\nexport const TopMenu = function() {\n const dispatch = useDispatch();\n\n let { mainView } = useShallowEqualSelector(state => state.appState);\n\n const [menuAnchorEl, setMenuAnchorEl] = React.useState(null);\n const menuOpen = Boolean(menuAnchorEl);\n const handleMenuClick = (event: React.MouseEvent) => {\n setMenuAnchorEl(event.currentTarget);\n };\n\n const handleMenuClose = () => {\n setMenuAnchorEl(null);\n };\n\n const handleWipeDisc = () => {\n dispatch(wipeDisc());\n handleMenuClose();\n };\n\n const handleRefresh = () => {\n dispatch(listContent());\n handleMenuClose();\n };\n\n const handleExit = () => {\n dispatch(appActions.setState('WELCOME'));\n handleMenuClose();\n };\n const handleShowAbout = () => {\n dispatch(appActions.showAboutDialog(true));\n handleMenuClose();\n };\n\n const menuItems = [];\n if (mainView === 'MAIN') {\n menuItems.push(\n \n Refresh\n \n );\n menuItems.push(\n \n Wipe Disc\n \n );\n menuItems.push(\n \n Exit\n \n );\n }\n menuItems.push(\n \n About\n \n );\n menuItems.push(\n \n \n Fork me on GitHub\n \n \n );\n\n return (\n \n \n \n \n \n {menuItems}\n \n \n );\n};\n","import React, { useState } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { pair } from '../redux/actions';\n\nimport { useShallowEqualSelector } from '../utils';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Button from '@material-ui/core/Button';\nimport Typography from '@material-ui/core/Typography';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport Box from '@material-ui/core/Box';\nimport Link from '@material-ui/core/Link';\n\nimport { AboutDialog } from './about-dialog';\nimport { TopMenu } from './topmenu';\nimport ChromeIconPath from '../images/chrome-icon.svg';\n\nconst useStyles = makeStyles(theme => ({\n main: {\n position: 'relative',\n flex: '1 1 auto',\n display: 'flex',\n justifyContent: 'center',\n flexDirection: 'column',\n alignItems: 'center',\n },\n button: {\n marginTop: theme.spacing(3),\n minWidth: 150,\n },\n spacing: {\n marginTop: theme.spacing(1),\n },\n chromeLogo: {\n marginTop: theme.spacing(1),\n width: 96,\n height: 96,\n },\n why: {\n alignSelf: 'flex-start',\n marginTop: theme.spacing(3),\n },\n headBox: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n}));\n\nexport const Welcome = (props: {}) => {\n const classes = useStyles();\n\n const dispatch = useDispatch();\n const { browserSupported, pairingFailed, pairingMessage } = useShallowEqualSelector(state => state.appState);\n if (pairingMessage.toLowerCase().match(/denied/)) {\n // show linux instructions\n }\n // Access denied.\n\n const [showWhyUnsupported, setWhyUnsupported] = useState(false);\n const handleLearnWhy = (event: React.SyntheticEvent) => {\n event.preventDefault();\n setWhyUnsupported(true);\n };\n\n return (\n \n \n \n Web MiniDisc\n \n \n \n \n Brings NetMD Devices to the Web\n \n \n {browserSupported ? (\n \n \n Press the button to connect to a NetMD device\n \n\n \n\n \n {pairingMessage}\n \n \n ) : (\n \n \n This Web browser is not supported. \n \n Learn Why\n \n \n\n \n \"Chrome\n \n\n \n Try using{' '}\n \n Chrome\n {' '}\n instead\n \n\n {showWhyUnsupported ? (\n <>\n \n Web MiniDisc requires a browser that supports both{' '}\n \n WebUSB\n {' '}\n and{' '}\n \n WebAssembly\n \n .\n \n
    \n
  • WebUSB is needed to control the NetMD device via the USB connection to your computer.
  • \n
  • WebAssembly is used to convert the music to a MiniDisc compatible format
  • \n
\n \n ) : null}\n
\n )}\n
\n \n
\n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { renameTrack } from '../redux/actions';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport TextField from '@material-ui/core/TextField';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nexport const RenameDialog = (props: {}) => {\n let dispatch = useDispatch();\n\n let renameDialogVisible = useShallowEqualSelector(state => state.renameDialog.visible);\n let renameDialogTitle = useShallowEqualSelector(state => state.renameDialog.title);\n let renameDialogIndex = useShallowEqualSelector(state => state.renameDialog.index);\n\n const handleCancelRename = () => {\n dispatch(renameDialogActions.setVisible(false));\n };\n\n const handleDoRename = () => {\n dispatch(renameTrack({ index: renameDialogIndex, newName: renameDialogTitle }));\n };\n\n return (\n \n Rename Track\n \n {\n event.key === `Enter` && handleDoRename();\n }}\n onChange={event => {\n dispatch(renameDialogActions.setCurrentName(event.target.value));\n }}\n />\n \n \n \n \n \n \n );\n};\n","import React from 'react';\nimport { useShallowEqualSelector } from '../utils';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\n\nconst useStyles = makeStyles(theme => ({\n progressPerc: {\n marginTop: theme.spacing(1),\n },\n progressBar: {\n marginTop: theme.spacing(3),\n },\n uploadLabel: {\n marginTop: theme.spacing(3),\n },\n}));\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nexport const UploadDialog = (props: {}) => {\n const classes = useStyles();\n\n let {\n visible,\n writtenProgress,\n encryptedProgress,\n totalProgress,\n\n trackTotal,\n trackCurrent,\n trackConverting,\n titleCurrent,\n titleConverting,\n } = useShallowEqualSelector(state => state.uploadDialog);\n\n let progressValue = Math.floor((writtenProgress / totalProgress) * 100);\n let bufferValue = Math.floor((encryptedProgress / totalProgress) * 100);\n let convertedValue = Math.floor((trackConverting / trackTotal) * 100);\n return (\n \n Recording...\n \n \n {convertedValue === 100 && trackConverting === trackTotal\n ? `Conversion completed`\n : `Converting ${trackConverting + 1} of ${trackTotal}: ${titleConverting}`}\n \n \n {convertedValue}%\n\n \n Uploading {trackCurrent} of {trackTotal}: {titleCurrent}\n \n \n {progressValue}%\n \n \n \n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as errorDialogActions } from '../redux/error-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nexport const ErrorDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let { visible, error } = useShallowEqualSelector(state => state.errorDialog);\n\n const handleClose = () => {\n dispatch(errorDialogActions.setVisible(false));\n };\n\n return (\n \n Error\n \n {error}\n \n \n \n \n \n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as convertDialogActions } from '../redux/convert-dialog-feature';\nimport { convertAndUpload } from '../redux/actions';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport FormControl from '@material-ui/core/FormControl';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport Select from '@material-ui/core/Select';\nimport Input from '@material-ui/core/Input';\nimport MenuItem from '@material-ui/core/MenuItem';\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nconst useStyles = makeStyles(theme => ({\n container: {\n display: 'flex',\n flexDirection: 'row',\n },\n formControl: {\n minWidth: 120,\n },\n}));\n\nexport const ConvertDialog = (props: { files: File[] }) => {\n const dispatch = useDispatch();\n const classes = useStyles();\n\n let { visible, format } = useShallowEqualSelector(state => state.convertDialog);\n\n const handleClose = () => {\n dispatch(convertDialogActions.setVisible(false));\n };\n\n const handleChange = (ev: React.ChangeEvent<{ value: unknown }>) => {\n dispatch(convertDialogActions.setFormat(ev.target.value as string));\n };\n\n const handleConvert = () => {\n handleClose();\n dispatch(convertAndUpload(props.files, format));\n };\n\n return (\n \n Upload Settings\n \n \n \n Format\n \n }\n >\n SP\n LP2\n LP4\n \n \n \n \n \n \n \n \n );\n};\n","import React, { useEffect, useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport clsx from 'clsx';\nimport { useDropzone } from 'react-dropzone';\nimport { listContent, deleteTracks } from '../redux/actions';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { actions as convertDialogActions } from '../redux/convert-dialog-feature';\n\nimport { formatTimeFromFrames, getTracks, Encoding } from 'netmd-js';\n\nimport { useShallowEqualSelector } from '../utils';\n\nimport { lighten, makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport Box from '@material-ui/core/Box';\nimport Fab from '@material-ui/core/Fab';\nimport AddIcon from '@material-ui/icons/Add';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport EditIcon from '@material-ui/icons/Edit';\nimport Backdrop from '@material-ui/core/Backdrop';\n\nimport Table from '@material-ui/core/Table';\nimport TableBody from '@material-ui/core/TableBody';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableHead from '@material-ui/core/TableHead';\nimport TableRow from '@material-ui/core/TableRow';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { batchActions } from 'redux-batched-actions';\n\nimport { RenameDialog } from './rename-dialog';\nimport { UploadDialog } from './upload-dialog';\nimport { ErrorDialog } from './error-dialog';\nimport { ConvertDialog } from './convert-dialog';\nimport { AboutDialog } from './about-dialog';\nimport { TopMenu } from './topmenu';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport * as BadgeImpl from '@material-ui/core/Badge/Badge';\n\nconst useStyles = makeStyles(theme => ({\n add: {\n position: 'absolute',\n bottom: theme.spacing(3),\n right: theme.spacing(3),\n },\n main: {\n overflowY: 'auto',\n flex: '1 1 auto',\n marginBottom: theme.spacing(3),\n marginLeft: theme.spacing(-2),\n marginRight: theme.spacing(-2),\n outline: 'none',\n },\n toolbar: {\n marginTop: theme.spacing(3),\n marginLeft: theme.spacing(-2),\n marginRight: theme.spacing(-2),\n [theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {\n marginLeft: theme.spacing(-3),\n marginRight: theme.spacing(-3),\n },\n },\n toolbarLabel: {\n flex: '1 1 100%',\n },\n toolbarHighlight:\n theme.palette.type === 'light'\n ? {\n color: theme.palette.secondary.main,\n backgroundColor: lighten(theme.palette.secondary.light, 0.85),\n }\n : {\n color: theme.palette.text.primary,\n backgroundColor: theme.palette.secondary.dark,\n },\n headBox: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n spacing: {\n marginTop: theme.spacing(1),\n },\n formatBadge: {\n ...(BadgeImpl as any).styles(theme).badge,\n ...(BadgeImpl as any).styles(theme).colorPrimary,\n position: 'static',\n display: 'inline-flex',\n border: `2px solid ${theme.palette.background.paper}`,\n padding: '0 4px',\n },\n titleCell: {\n overflow: 'hidden',\n maxWidth: '40ch',\n textOverflow: 'ellipsis',\n // whiteSpace: 'nowrap',\n },\n backdrop: {\n zIndex: theme.zIndex.drawer + 1,\n color: '#fff',\n },\n}));\n\nconst EncodingName: { [k: number]: string } = {\n [Encoding.sp]: 'SP',\n [Encoding.lp2]: 'LP2',\n [Encoding.lp4]: 'LP4',\n};\n\nexport const Main = (props: {}) => {\n let dispatch = useDispatch();\n let disc = useShallowEqualSelector(state => state.main.disc);\n let deviceName = useShallowEqualSelector(state => state.main.deviceName);\n\n const [selected, setSelected] = React.useState([]);\n const selectedCount = selected.length;\n\n useEffect(() => {\n dispatch(listContent());\n }, [dispatch]);\n\n useEffect(() => {\n setSelected([]); // Reset selection if disc changes\n }, [disc]);\n\n let [uploadedFiles, setUploadedFiles] = React.useState([]);\n const onDrop = useCallback(\n (acceptedFiles: File[], rejectedFiles: File[]) => {\n setUploadedFiles(acceptedFiles);\n dispatch(convertDialogActions.setVisible(true));\n },\n [dispatch]\n );\n const { getRootProps, getInputProps, isDragActive, open } = useDropzone({ onDrop, accept: `audio/*`, noClick: true });\n\n const classes = useStyles();\n\n let tracks: { index: number; title: string; group: string; duration: string; encoding: string }[] = [];\n if (disc !== null) {\n for (let group of disc.groups) {\n for (let track of group.tracks) {\n tracks.push({\n index: track.index,\n title: track.title ?? `Unknown Title`,\n group: group.title ?? ``,\n encoding: EncodingName[track.encoding],\n duration: formatTimeFromFrames(track.duration, false),\n });\n }\n }\n }\n\n // Action Handlers\n const handleSelectClick = (event: React.MouseEvent, item: number) => {\n if (selected.includes(item)) {\n setSelected(selected.filter(i => i !== item));\n } else {\n setSelected([...selected, item]);\n }\n };\n\n const handleSelectAllClick = (event: React.ChangeEvent) => {\n if (selected.length < tracks.length) {\n setSelected(tracks.map(t => t.index));\n } else {\n setSelected([]);\n }\n };\n\n const handleRenameDoubleClick = (event: React.MouseEvent, item: number) => {\n let selectedIndex = item;\n let currentName = getTracks(disc!).find(track => track.index === selectedIndex)?.title ?? '';\n\n dispatch(\n batchActions([\n renameDialogActions.setVisible(true),\n renameDialogActions.setCurrentName(currentName),\n renameDialogActions.setIndex(selectedIndex),\n ])\n );\n };\n\n const handleRenameActionClick = (event: React.MouseEvent) => {\n handleRenameDoubleClick(event, selected[0]);\n };\n\n const handleDeleteSelected = (event: React.MouseEvent) => {\n dispatch(deleteTracks(selected));\n };\n\n return (\n \n \n \n {deviceName || `Loading...`}\n \n \n \n \n {disc !== null\n ? `${formatTimeFromFrames(disc.left, false)} left of ${formatTimeFromFrames(disc.total, false)}`\n : `Loading...`}\n \n 0,\n })}\n >\n {selectedCount > 0 ? (\n 0 && selectedCount < tracks.length}\n checked={selectedCount > 0}\n onChange={handleSelectAllClick}\n inputProps={{ 'aria-label': 'select all tracks' }}\n />\n ) : null}\n {selectedCount > 0 ? (\n \n {selectedCount} selected\n \n ) : (\n \n Content\n \n )}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n \n \n \n \n \n \n Title\n Format\n Duration\n \n \n \n {tracks.map(track => (\n handleRenameDoubleClick(event, track.index)}\n onClick={event => handleSelectClick(event, track.index)}\n >\n \n {track.title || `No Title`}\n \n \n {track.encoding}\n \n {track.duration}\n \n ))}\n \n
\n \n Drop your Music to Upload\n \n
\n \n \n \n\n \n \n \n \n \n
\n );\n};\n","import React from 'react';\nimport { useShallowEqualSelector } from '../utils';\nimport { actions as appActions } from '../redux/app-feature';\n\nimport CssBaseline from '@material-ui/core/CssBaseline';\nimport Backdrop from '@material-ui/core/Backdrop';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport { makeStyles, createMuiTheme, ThemeProvider } from '@material-ui/core/styles';\n\nimport { Welcome } from './welcome';\nimport { Main } from './main';\nimport Paper from '@material-ui/core/Paper';\nimport Typography from '@material-ui/core/Typography';\nimport Link from '@material-ui/core/Link';\nimport Box from '@material-ui/core/Box';\nimport Brightness2Icon from '@material-ui/icons/Brightness2';\nimport IconButton from '@material-ui/core/IconButton';\nimport { useDispatch } from 'react-redux';\n\nconst useStyles = makeStyles(theme => ({\n layout: {\n width: 'auto',\n height: '100%',\n [theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {\n width: 600,\n marginLeft: 'auto',\n marginRight: 'auto',\n },\n },\n\n paper: {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n padding: theme.spacing(2),\n height: '100%',\n [theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {\n marginTop: theme.spacing(6),\n marginBottom: theme.spacing(6),\n padding: theme.spacing(3),\n height: 600,\n },\n },\n copyright: {\n display: 'flex',\n alignItems: 'center',\n },\n backdrop: {\n zIndex: theme.zIndex.drawer + 1,\n color: '#fff',\n },\n minidiscLogo: {\n width: 48,\n },\n}));\n\nconst darkTheme = createMuiTheme({\n palette: {\n type: 'dark',\n primary: {\n light: '#6ec6ff',\n main: '#2196f3',\n dark: '#0069c0',\n contrastText: '#fff',\n },\n },\n});\n\nconst lightTheme = createMuiTheme({\n palette: {\n type: 'light',\n },\n});\n\nconst App = () => {\n const classes = useStyles();\n\n const dispatch = useDispatch();\n let { mainView, loading, darkMode } = useShallowEqualSelector(state => state.appState);\n\n return (\n \n \n \n\n
\n \n {mainView === 'WELCOME' ? : null}\n {mainView === 'MAIN' ?
: null}\n\n \n dispatch(appActions.setDarkMode(!darkMode))}>\n \n \n \n {'© '}\n \n Stefano Brilli\n {' '}\n {new Date().getFullYear()}\n {'.'}\n \n \n Tweet\n \n \n \n \n
\n\n \n \n \n \n \n );\n};\n\nexport default App;\n","import { createWorker, setLogging } from '@ffmpeg/ffmpeg';\nimport { AtracdencProcess } from './atracdenc-worker';\nimport { getPublicPathFor } from '../utils';\nconst AtracdencWorker = require('worker-loader!./atracdenc-worker'); // eslint-disable-line import/no-webpack-loader-syntax\n\ninterface LogPayload {\n message: string;\n action: string;\n}\n\nexport interface AudioExportService {\n init(): Promise;\n export(params: { format: string }): Promise;\n info(): Promise<{ format: string | null; input: string | null }>;\n prepare(file: File): Promise;\n}\n\nexport class FFMpegAudioExportService implements AudioExportService {\n public ffmpegProcess: any;\n public atracdencProcess?: AtracdencProcess;\n public loglines: { action: string; message: string }[] = [];\n public inFileName: string = ``;\n public outFileNameNoExt: string = ``;\n\n async init() {\n setLogging(true);\n }\n\n async prepare(file: File) {\n this.loglines = [];\n this.ffmpegProcess = createWorker({\n logger: (payload: LogPayload) => {\n this.loglines.push(payload);\n console.log(payload.action, payload.message);\n },\n corePath: getPublicPathFor('ffmpeg-core.js'),\n workerPath: getPublicPathFor('worker.min.js'),\n });\n await this.ffmpegProcess.load();\n\n this.atracdencProcess = new AtracdencProcess(new AtracdencWorker());\n await this.atracdencProcess.init();\n\n let ext = file.name.split('.').slice(-1);\n if (ext.length === 0) {\n throw new Error(`Unrecognized file format: ${file.name}`);\n }\n\n this.inFileName = `inAudioFile.${ext[0]}`;\n this.outFileNameNoExt = `outAudioFile`;\n\n await this.ffmpegProcess.write(this.inFileName, file);\n }\n\n async info() {\n await this.ffmpegProcess.transcode(this.inFileName, `${this.outFileNameNoExt}.metadata`, `-f ffmetadata`);\n\n let audioFormatRegex = /Audio:\\s(.*?),/; // Actual content\n let inputFormatRegex = /Input #0,\\s(.*?),/; // Container\n let format: string | null = null;\n let input: string | null = null;\n\n for (let line of this.loglines) {\n let match = line.message.match(audioFormatRegex);\n if (match !== null) {\n format = match[1];\n continue;\n }\n match = line.message.match(inputFormatRegex);\n if (match !== null) {\n input = match[1];\n continue;\n }\n if (format !== null && input !== null) {\n break;\n }\n }\n\n return { format, input };\n }\n\n async export({ format }: { format: string }) {\n if (format === `SP`) {\n const outFileName = `${this.outFileNameNoExt}.raw`;\n await this.ffmpegProcess.transcode(this.inFileName, outFileName, '-f s16be -ar 44100');\n let { data } = await this.ffmpegProcess.read(outFileName);\n return data.buffer;\n } else {\n const outFileName = `${this.outFileNameNoExt}.wav`;\n await this.ffmpegProcess.transcode(this.inFileName, outFileName, '-f wav -ar 44100');\n let { data } = await this.ffmpegProcess.read(outFileName);\n let bitrate: string = `0`;\n switch (format) {\n case `LP2`:\n bitrate = `128`;\n break;\n case `LP105`:\n bitrate = `102`;\n break;\n case `LP4`:\n bitrate = `64`;\n break;\n }\n let result = await this.atracdencProcess!.encode(data.buffer, bitrate);\n return result;\n }\n }\n}\n","/* eslint no-restricted-globals: 0 */\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Provider } from 'react-redux';\nimport * as serviceWorker from './serviceWorker';\nimport { NetMDUSBService } from './services/netmd';\nimport serviceRegistry from './services/registry';\n\nimport { store } from './redux/store';\nimport { actions as appActions } from './redux/app-feature';\n\nimport App from './components/app';\n\nimport './index.css';\nimport { FFMpegAudioExportService } from './services/audio-export';\n\nserviceRegistry.netmdService = new NetMDUSBService();\nserviceRegistry.audioExportService = new FFMpegAudioExportService();\n\n(function setupEventHandlers() {\n window.addEventListener('beforeunload', ev => {\n let isUploading = store.getState().uploadDialog.visible;\n if (!isUploading) {\n return;\n }\n ev.preventDefault();\n ev.returnValue = `Warning! Recording will be interrupted`;\n });\n\n if (navigator && navigator.usb) {\n navigator.usb.ondisconnect = function() {\n store.dispatch(appActions.setState('WELCOME'));\n };\n } else {\n store.dispatch(appActions.setBrowserSupported(false));\n }\n\n // eslint-disable-next-line\n let deferredPrompt: any;\n window.addEventListener('beforeinstallprompt', (e: any) => {\n e.preventDefault();\n deferredPrompt = e;\n });\n})();\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// serviceWorker.unregister();\nserviceWorker.register();\n"],"sourceRoot":""} \ No newline at end of file diff --git a/static/js/main.79696204.chunk.js b/static/js/main.a222d332.chunk.js similarity index 86% rename from static/js/main.79696204.chunk.js rename to static/js/main.a222d332.chunk.js index d0c85b0..5d3467c 100644 --- a/static/js/main.79696204.chunk.js +++ b/static/js/main.a222d332.chunk.js @@ -1,2 +1,2 @@ -(this.webpackJsonpwebmd=this.webpackJsonpwebmd||[]).push([[0],{215:function(e,t,a){e.exports=a.p+"static/media/chrome-icon.f3b6c54c.svg"},241:function(e,t,a){e.exports=a(411)},257:function(e,t){},259:function(e,t){},292:function(e,t){},293:function(e,t){},391:function(e,t,a){},410:function(e,t,a){e.exports=function(){return new Worker(a.p+"cc43d050d6e858b79f86.worker.js")}},411:function(e,t,a){"use strict";a.r(t);var n=a(0),r=a.n(n),i=a(15),c=a.n(i),o=a(17),l=Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));function s(e,t){navigator.serviceWorker.register(e).then((function(e){e.onupdatefound=function(){var a=e.installing;null!=a&&(a.onstatechange=function(){console.log("state change",a.state),"installed"===a.state&&(navigator.serviceWorker.controller?(console.log("New content is available and will be used when all tabs for this page are closed. See https://bit.ly/CRA-PWA."),t&&t.onUpdate&&t.onUpdate(e)):(console.log("Content is cached for offline use."),t&&t.onSuccess&&t.onSuccess(e)))})},e.update()})).catch((function(e){console.error("Error during service worker registration:",e)}))}var u=a(6),p=a.n(u),m=a(16),f=a(43),d=a(30),b=a(20),g=a(211),h=a(359),v=function(){function e(){Object(f.a)(this,e),this.netmdInterface=void 0}return Object(d.a)(e,[{key:"pair",value:function(){var e=Object(m.a)(p.a.mark((function e(){var t;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Object(b.openNewDevice)(navigator.usb);case 2:if(null!==(t=e.sent)){e.next=5;break}return e.abrupt("return",!1);case 5:return this.netmdInterface=t,e.abrupt("return",!0);case 7:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"connect",value:function(){var e=Object(m.a)(p.a.mark((function e(){var t;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Object(b.openPairedDevice)(navigator.usb);case 2:if(null!==(t=e.sent)){e.next=5;break}return e.abrupt("return",!1);case 5:return this.netmdInterface=t,e.abrupt("return",!0);case 7:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"listContent",value:function(){var e=Object(m.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Object(b.listContent)(this.netmdInterface);case 2:return e.abrupt("return",e.sent);case 3:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"getDeviceName",value:function(){var e=Object(m.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.netMd.getDeviceName();case 2:return e.abrupt("return",e.sent);case 3:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"finalize",value:function(){var e=Object(m.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.netMd.finalize();case 2:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"renameTrack",value:function(){var e=Object(m.a)(p.a.mark((function e(t,a){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.setTrackTitle(t,a);case 2:case"end":return e.stop()}}),e,this)})));return function(t,a){return e.apply(this,arguments)}}()},{key:"deleteTrack",value:function(){var e=Object(m.a)(p.a.mark((function e(t){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.eraseTrack(t);case 2:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}()},{key:"wipeDisc",value:function(){var e=Object(m.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.eraseDisc();case 2:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"upload",value:function(){var e=Object(m.a)(p.a.mark((function e(t,a,n,r){var i,c,o,l,s,u,m;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return l=function(){r({written:c,encrypted:o,total:i})},i=a.byteLength,c=0,o=0,s=new h,u=Object(g.makeGetAsyncPacketIteratorOnWorkerThread)(s,(function(e){var t=e.encryptedBytes;o=t,l()})),m=new b.MDTrack(t,n,a,524288,u),e.next=9,Object(b.download)(this.netmdInterface,m,(function(e){var t=e.writtenBytes;c=t,l()}));case 9:case"end":return e.stop()}}),e,this)})));return function(t,a,n,r){return e.apply(this,arguments)}}()}]),e}(),k={},w=a(24),E=a(28),y=a(19),x=Object(E.b)({name:"uploadDialog",initialState:{visible:!1,writtenProgress:0,encryptedProgress:0,totalProgress:1,trackTotal:1,trackConverting:0,trackCurrent:0,titleCurrent:"",titleConverting:""},reducers:{setVisible:function(e,t){e.visible=t.payload},setWriteProgress:function(e,t){e.encryptedProgress=t.payload.encrypted,e.writtenProgress=t.payload.written,e.totalProgress=t.payload.total},setTrackProgress:function(e,t){e.trackTotal=t.payload.total,e.trackCurrent=t.payload.current,e.trackConverting=t.payload.converting,e.titleCurrent=t.payload.titleCurrent,e.titleConverting=t.payload.titleConverting}}}),j=x.reducer,O=x.actions,C=Object(y.enableBatching)(j),N=Object(E.b)({name:"renameDialog",initialState:{visible:!1,title:"",index:-1},reducers:{setVisible:function(e,t){e.visible=t.payload},setCurrentName:function(e,t){e.title=t.payload},setIndex:function(e,t){e.index=t.payload}}}),S=N.reducer,P=N.actions,D=Object(y.enableBatching)(S),F=Object(E.b)({name:"errorDialog",initialState:{visible:!1,error:""},reducers:{setVisible:function(e,t){e.visible=t.payload},setErrorMessage:function(e,t){e.error="".concat(t.payload)}}}),M=F.actions,W=F.reducer,L=Object(y.enableBatching)(W),T=Object(E.b)({name:"convertDialog",initialState:{visible:!1,format:"LP2"},reducers:{setVisible:function(e,t){e.visible=t.payload},setFormat:function(e,t){e.format=t.payload}}}),A=T.actions,B=T.reducer,I=Object(y.enableBatching)(B);function V(e){return Object(o.d)(e,o.b)}function R(e){return"".concat("/webminidisc","/").concat(e)}var _={mainView:"WELCOME",loading:!1,pairingFailed:!1,pairingMessage:"",browserSupported:!0,darkMode:function(e,t){var a=localStorage.getItem(e);if(null===a)return t;try{return JSON.parse(a)}catch(n){return t}}("darkMode",!1),aboutDialogVisible:!1},U=Object(E.b)({name:"app",initialState:_,reducers:{setState:function(e,t){e.mainView=t.payload},setLoading:function(e,t){e.loading=t.payload},setPairingFailed:function(e,t){e.pairingFailed=t.payload},setPairingMessage:function(e,t){e.pairingMessage=t.payload},setBrowserSupported:function(e,t){e.browserSupported=t.payload},setDarkMode:function(e,t){var a,n;e.darkMode=t.payload,a="darkMode",n=e.darkMode,localStorage.setItem(a,JSON.stringify(n))},showAboutDialog:function(e,t){e.aboutDialogVisible=t.payload}}}),z=U.reducer,J=U.actions,G=Object(y.enableBatching)(z),H=Object(E.b)({name:"main",initialState:{disc:null,deviceName:""},reducers:{setDisc:function(e,t){e.disc=t.payload},setDeviceName:function(e,t){e.deviceName=t.payload}}}),Y=H.reducer,q=H.actions,K=Object(y.enableBatching)(Y),$=Object(E.a)({reducer:{renameDialog:D,uploadDialog:C,errorDialog:L,convertDialog:I,appState:G,main:K},middleware:Object(w.a)(Object(E.c)())}),Q=a(11),X=a(474),Z=a(416),ee=a(475),te=a(462),ae=a(223),ne=a(466),re=a(27),ie=(a(365),a(226)),ce=a(213);function oe(){return function(){var e=Object(m.a)(p.a.mark((function e(t){var a,n;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t(J.setLoading(!0)),e.next=3,k.netmdService.listContent();case 3:return a=e.sent,e.next=6,k.netmdService.getDeviceName();case 6:n=e.sent,t(Object(y.batchActions)([q.setDisc(a),q.setDeviceName(n),J.setLoading(!1)]));case 8:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()}var le={SP:b.Wireformat.pcm,LP2:b.Wireformat.lp2,LP105:b.Wireformat.l105kbps,LP4:b.Wireformat.lp4};var se,ue,pe=a(459),me=a(145),fe=a(417),de=a(418),be=a(476),ge=a(457),he=a(451),ve=a(458),ke=a(455),we=a(456),Ee=a(454),ye=a(450),xe=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),je=function(e){var t=Object(o.c)(),a=V((function(e){return e.appState.aboutDialogVisible}));return r.a.createElement(he.a,{open:a,maxWidth:"sm",fullWidth:!0,TransitionComponent:xe,"aria-labelledby":"about-dialog-slide-title"},r.a.createElement(Ee.a,{id:"about-dialog-slide-title"},"About Web MiniDisc"),r.a.createElement(ke.a,null,r.a.createElement(we.a,null,"Web MiniDisc has been made possible by"),r.a.createElement("ul",null,r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://www.ffmpeg.org/",target:"_blank"},"FFmpeg")," ","and"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/ffmpegjs/FFmpeg",target:"_blank"},"ffmpegjs"),", to read your audio files (wav, mp3, ogg, mp4, etc...)."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/dcherednik/atracdenc/",target:"_blank"},"Atracdenc"),", to support atrac3 encoding (lp2, lp4 audio formats)."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://emscripten.org/",target:"_blank"},"Emscripten"),", to run both FFmpeg and Atracdenc in the browser."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/cybercase/netmd-js",target:"_blank"},"netmd-js"),", to send commands to NetMD devices using Javascript."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/glaubitz/linux-minidisc",target:"_blank"},"linux-minidisc"),", to make the netmd-js project possible."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://material-ui.com/",target:"_blank"},"material-ui"),", to build the user interface.")),r.a.createElement(we.a,null,"Attribution"),r.a.createElement("ul",null,r.a.createElement("li",null,"MiniDisc logo from"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://en.wikipedia.org/wiki/MiniDisc",target:"_blank"},"https://en.wikipedia.org/wiki/MiniDisc")),r.a.createElement("li",null,"MiniDisc icon from"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://www.deviantart.com/blinkybill/art/Sony-MiniDisc-Plastic-Icon-473812540",target:"_blank"},"http://fav.me/d7u3g3g")))),r.a.createElement(ve.a,null,r.a.createElement(pe.a,{onClick:function(){t(J.showAboutDialog(!1))}},"Close")))},Oe=a(460),Ce=a(225),Ne=a(479),Se=a(214),Pe=a.n(Se),De=function(){var e=Object(o.c)(),t=V((function(e){return e.appState})).mainView,a=r.a.useState(null),n=Object(re.a)(a,2),i=n[0],c=n[1],l=Boolean(i),s=function(){c(null)},u=[];return"MAIN"===t&&(u.push(r.a.createElement(Ne.a,{key:"update",onClick:function(){e(oe()),s()}},"Refresh")),u.push(r.a.createElement(Ne.a,{key:"wipe",onClick:function(){e(function(){var e=Object(m.a)(p.a.mark((function e(t){var a;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=k.netmdService,t(J.setLoading(!0)),e.next=4,a.wipeDisc();case 4:oe()(t);case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),s()}},"Wipe Disc")),u.push(r.a.createElement(Ne.a,{key:"exit",onClick:function(){e(J.setState("WELCOME")),s()}},"Exit"))),u.push(r.a.createElement(Ne.a,{key:"about",onClick:function(){e(J.showAboutDialog(!0)),s()}},"About")),u.push(r.a.createElement(Ne.a,{key:"github",onClick:s},r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/cybercase/webminidisc",target:"_blank"},"Fork me on GitHub"))),r.a.createElement(r.a.Fragment,null,r.a.createElement(Oe.a,{"aria-label":"actions","aria-controls":"actions-menu","aria-haspopup":"true",onClick:function(e){c(e.currentTarget)}},r.a.createElement(Pe.a,null)),r.a.createElement(Ce.a,{id:"actions-menu",anchorEl:i,keepMounted:!0,open:l,onClose:s},u))},Fe=a(215),Me=a.n(Fe),We=Object(te.a)((function(e){return{main:{position:"relative",flex:"1 1 auto",display:"flex",justifyContent:"center",flexDirection:"column",alignItems:"center"},button:{marginTop:e.spacing(3),minWidth:150},spacing:{marginTop:e.spacing(1)},chromeLogo:{marginTop:e.spacing(1),width:96,height:96},why:{alignSelf:"flex-start",marginTop:e.spacing(3)},headBox:{display:"flex",justifyContent:"space-between"}}})),Le=function(e){var t=We(),a=Object(o.c)(),i=V((function(e){return e.appState})),c=i.browserSupported,l=i.pairingFailed,s=i.pairingMessage;s.toLowerCase().match(/denied/);var u=Object(n.useState)(!1),f=Object(re.a)(u,2),d=f[0],b=f[1];return r.a.createElement(r.a.Fragment,null,r.a.createElement(be.a,{className:t.headBox},r.a.createElement(me.a,{component:"h1",variant:"h4"},"Web MiniDisc"),r.a.createElement(De,null)),r.a.createElement(me.a,{component:"h2",variant:"body2"},"Brings NetMD Devices to the Web"),r.a.createElement(be.a,{className:t.main},c?r.a.createElement(r.a.Fragment,null,r.a.createElement(me.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"Press the button to connect to a NetMD device"),r.a.createElement(pe.a,{variant:"contained",color:"primary",onClick:function(){return a(function(){var e=Object(m.a)(p.a.mark((function e(t,a){var n;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t(J.setPairingFailed(!1)),e.next=3,k.audioExportService.init();case 3:return e.prev=3,e.next=6,k.netmdService.connect();case 6:if(!e.sent){e.next=10;break}return t(J.setState("MAIN")),e.abrupt("return");case 10:e.next=15;break;case 12:e.prev=12,e.t0=e.catch(3),console.error(e.t0);case 15:return e.prev=15,e.next=18,k.netmdService.pair();case 18:if(!e.sent){e.next=22;break}return t(J.setState("MAIN")),e.abrupt("return");case 22:t(Object(y.batchActions)([J.setPairingMessage("Connection Failed"),J.setPairingFailed(!0)])),e.next=30;break;case 25:e.prev=25,e.t1=e.catch(15),console.error(e.t1),n=e.t1.message,t(Object(y.batchActions)([J.setPairingMessage(n),J.setPairingFailed(!0)]));case 30:case"end":return e.stop()}}),e,null,[[3,12],[15,25]])})));return function(t,a){return e.apply(this,arguments)}}())},className:t.button},"Connect"),r.a.createElement(fe.a,{error:!0,className:t.spacing,style:{visibility:l?"visible":"hidden"}},r.a.createElement(de.a,null,s))):r.a.createElement(r.a.Fragment,null,r.a.createElement(me.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"This Web browser is not supported.\xa0",r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"#",onClick:function(e){e.preventDefault(),b(!0)}},"Learn Why")),r.a.createElement(ge.a,{rel:"noopener noreferrer",target:"_blank",href:"https://www.google.com/chrome/"},r.a.createElement("img",{alt:"Chrome Logo",src:Me.a,className:t.chromeLogo})),r.a.createElement(me.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"Try using"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",target:"_blank",href:"https://www.google.com/chrome/"},"Chrome")," ","instead"),d?r.a.createElement(r.a.Fragment,null,r.a.createElement(me.a,{component:"p",variant:"body2",className:t.why},"Web MiniDisc requires a browser that supports both"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",target:"_blank",href:"https://wicg.github.io/webusb/"},"WebUSB")," ","and"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",target:"_blank",href:"https://webassembly.org/"},"WebAssembly"),"."),r.a.createElement("ul",null,r.a.createElement("li",null,"WebUSB is needed to control the NetMD device via the USB connection to your computer."),r.a.createElement("li",null,"WebAssembly is used to convert the music to a MiniDisc compatible format"))):null)),r.a.createElement(je,null))},Te=a(216),Ae=a(3),Be=a(224),Ie=a(14),Ve=a(473),Re=a(221),_e=a.n(Re),Ue=a(219),ze=a.n(Ue),Je=a(220),Ge=a.n(Je),He=a(468),Ye=a(472),qe=a(471),Ke=a(469),$e=a(470),Qe=a(467),Xe=a(478),Ze=a(464),et=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),tt=function(e){var t=Object(o.c)(),a=V((function(e){return e.renameDialog.visible})),n=V((function(e){return e.renameDialog.title})),i=V((function(e){return e.renameDialog.index})),c=function(){t(P.setVisible(!1))},l=function(){t(function(e){var t=e.index,a=e.newName;return(function(){var e=Object(m.a)(p.a.mark((function e(n){var r;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=k.netmdService,e.next=3,r.renameTrack(t,a);case 3:n(P.setVisible(!1)),oe()(n);case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}())}({index:i,newName:n}))};return r.a.createElement(he.a,{open:a,onClose:c,maxWidth:"sm",fullWidth:!0,TransitionComponent:et,"aria-labelledby":"rename-dialog-title"},r.a.createElement(Ee.a,{id:"rename-dialog-title"},"Rename Track"),r.a.createElement(ke.a,null,r.a.createElement(Ze.a,{autoFocus:!0,id:"name",label:"Track Name",type:"text",fullWidth:!0,value:n,onKeyDown:function(e){"Enter"===e.key&&l()},onChange:function(e){t(P.setCurrentName(e.target.value))}})),r.a.createElement(ve.a,null,r.a.createElement(pe.a,{onClick:c},"Cancel"),r.a.createElement(pe.a,{color:"primary",onClick:l},"Rename")))},at=a(465),nt=Object(te.a)((function(e){return{progressPerc:{marginTop:e.spacing(1)},progressBar:{marginTop:e.spacing(3)},uploadLabel:{marginTop:e.spacing(3)}}})),rt=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),it=function(e){var t=nt(),a=V((function(e){return e.uploadDialog})),n=a.visible,i=a.writtenProgress,c=a.encryptedProgress,o=a.totalProgress,l=a.trackTotal,s=a.trackCurrent,u=a.trackConverting,p=a.titleCurrent,m=a.titleConverting,f=Math.floor(i/o*100),d=Math.floor(c/o*100),b=Math.floor(u/l*100);return r.a.createElement(he.a,{open:n,maxWidth:"sm",fullWidth:!0,TransitionComponent:rt,"aria-labelledby":"alert-dialog-slide-title","aria-describedby":"alert-dialog-slide-description"},r.a.createElement(Ee.a,{id:"alert-dialog-slide-title"},"Recording..."),r.a.createElement(ke.a,null,r.a.createElement(we.a,{id:"alert-dialog-slide-description"},100===b&&u===l?"Conversion completed":"Converting ".concat(u+1," of ").concat(l,": ").concat(m)),r.a.createElement(at.a,{className:t.progressBar,variant:0===b?"indeterminate":"determinate",color:"primary",value:b}),r.a.createElement(be.a,{className:t.progressPerc},b,"%"),r.a.createElement(we.a,{id:"alert-dialog-slide-description",className:t.uploadLabel},"Uploading ",s," of ",l,": ",p),r.a.createElement(at.a,{className:t.progressBar,variant:"buffer",color:"secondary",value:f,valueBuffer:d}),r.a.createElement(be.a,{className:t.progressPerc},f,"%")),r.a.createElement(ve.a,null))},ct=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),ot=function(e){var t=Object(o.c)(),a=V((function(e){return e.errorDialog})),n=a.visible,i=a.error;return r.a.createElement(he.a,{open:n,maxWidth:"sm",fullWidth:!0,TransitionComponent:ct,"aria-labelledby":"error-dialog-slide-title","aria-describedby":"error-dialog-slide-description"},r.a.createElement(Ee.a,{id:"alert-dialog-slide-title"},"Error"),r.a.createElement(ke.a,null,r.a.createElement(we.a,{id:"alert-dialog-slide-description"},i)),r.a.createElement(ve.a,null,r.a.createElement(pe.a,{onClick:function(){t(M.setVisible(!1))}},"Close")))},lt=a(423),st=a(421),ut=a(419),pt=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),mt=Object(te.a)((function(e){return{container:{display:"flex",flexDirection:"row"},formControl:{minWidth:120}}})),ft=function(e){var t=Object(o.c)(),a=mt(),n=V((function(e){return e.convertDialog})),i=n.visible,c=n.format,l=function(){t(A.setVisible(!1))};return r.a.createElement(he.a,{open:i,maxWidth:"xs",fullWidth:!0,TransitionComponent:pt,"aria-labelledby":"convert-dialog-slide-title","aria-describedby":"convert-dialog-slide-description"},r.a.createElement(Ee.a,{id:"convert-dialog-slide-title"},"Upload Settings"),r.a.createElement(ke.a,null,r.a.createElement(fe.a,{className:a.formControl},r.a.createElement(lt.a,{color:"secondary",id:"convert-dialog-format"},"Format"),r.a.createElement(st.a,{labelId:"convert-dialog-format-label",id:"convert-dialog-format",value:c,color:"secondary",onChange:function(e){t(A.setFormat(e.target.value))},input:r.a.createElement(ut.a,null)},r.a.createElement(Ne.a,{value:"SP"},"SP"),r.a.createElement(Ne.a,{value:"LP2"},"LP2"),r.a.createElement(Ne.a,{value:"LP4"},"LP4")))),r.a.createElement(ve.a,null,r.a.createElement(pe.a,{onClick:l},"Cancel"),r.a.createElement(pe.a,{onClick:function(){l(),t(function(e,t){return function(){var a=Object(m.a)(p.a.mark((function a(n,r){var i,c,o,l,s,u,f,d,b,g,h,v,w,E,x,j,C,N,S,P;return p.a.wrap((function(a){for(;;)switch(a.prev=a.next){case 0:i=k.audioExportService,c=k.netmdService,o=le[t],n(O.setVisible(!0)),l=function(e){var t=e.written,a=e.encrypted,r=e.total;n(O.setWriteProgress({written:t,encrypted:a,total:r}))},s={current:0,converting:0,total:e.length,titleCurrent:"",titleConverting:""},u=function(){n(O.setTrackProgress(s))},f=function(){var e=Object(ie.a)(p.a.mark((function e(a){var n,r,c,o;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:c=function(){if(r===a.length)return s.converting=r,s.titleConverting="",void u();var e=a[r];s.converting=r,s.titleConverting=e.name,u(),r++,n.push(new Promise(function(){var a=Object(m.a)(p.a.mark((function a(n,r){var o;return p.a.wrap((function(a){for(;;)switch(a.prev=a.next){case 0:return a.prev=0,a.next=3,i.prepare(e);case 3:return a.next=5,i.export({format:t});case 5:o=a.sent,c(),n({file:e,data:o}),a.next=15;break;case 10:a.prev=10,a.t0=a.catch(0),d=a.t0,b="".concat(e.name,": Unsupported or unrecognized format"),r(a.t0);case 15:case"end":return a.stop()}}),a,null,[[0,10]])})));return function(e,t){return a.apply(this,arguments)}}()))},n=[],r=0,c(),o=0;case 5:if(!(o0))},f>0?r.a.createElement(dt.a,{indeterminate:f>0&&f0,onChange:function(e){s.length0?r.a.createElement(me.a,{className:S.toolbarLabel,color:"inherit",variant:"subtitle1"},f," selected"):r.a.createElement(me.a,{component:"h3",variant:"h6",className:S.toolbarLabel},"Content"),f>0?r.a.createElement(Xe.a,{title:"Delete"},r.a.createElement(Oe.a,{"aria-label":"delete",onClick:function(e){var a;t((a=s,function(){var e=Object(m.a)(p.a.mark((function e(t){var n,r,i,c,o,l,s;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:n=k.netmdService,t(J.setLoading(!0)),(a=a.sort()).reverse(),r=!0,i=!1,c=void 0,e.prev=7,o=a[Symbol.iterator]();case 9:if(r=(l=o.next()).done){e.next=16;break}return s=l.value,e.next=13,n.deleteTrack(s);case 13:r=!0,e.next=9;break;case 16:e.next=22;break;case 18:e.prev=18,e.t0=e.catch(7),i=!0,c=e.t0;case 22:e.prev=22,e.prev=23,r||null==o.return||o.return();case 25:if(e.prev=25,!i){e.next=28;break}throw c;case 28:return e.finish(25);case 29:return e.finish(22);case 30:oe()(t);case 31:case"end":return e.stop()}}),e,null,[[7,18,22,30],[23,,25,29]])})));return function(t){return e.apply(this,arguments)}}()))}},r.a.createElement(ze.a,null))):null,f>0?r.a.createElement(Xe.a,{title:"Rename"},r.a.createElement(Oe.a,{"aria-label":"rename",disabled:1!==f,onClick:function(e){q(0,s[0])}},r.a.createElement(Ge.a,null))):null),r.a.createElement(be.a,Object.assign({className:S.main},j()),r.a.createElement("input",O()),r.a.createElement(He.a,{size:"small"},r.a.createElement(Ke.a,null,r.a.createElement($e.a,null,r.a.createElement(qe.a,null,"Title"),r.a.createElement(qe.a,null,"Format"),r.a.createElement(qe.a,{align:"right"},"Duration"))),r.a.createElement(Ye.a,null,D.map((function(e){return r.a.createElement($e.a,{hover:!0,selected:s.includes(e.index),key:e.index,onDoubleClick:function(t){return q(0,e.index)},onClick:function(t){return a=e.index,void(s.includes(a)?u(s.filter((function(e){return e!==a}))):u([].concat(Object(w.a)(s),[a])));var a}},r.a.createElement(qe.a,{className:S.titleCell,title:e.title},e.title||"No Title"),r.a.createElement(qe.a,null,r.a.createElement("span",{className:S.formatBadge},e.encoding)),r.a.createElement(qe.a,{align:"right"},e.duration))})))),r.a.createElement(Z.a,{className:S.backdrop,open:C},"Drop your Music to Upload")),r.a.createElement(Ve.a,{color:"primary","aria-label":"add",className:S.add,onClick:N},r.a.createElement(_e.a,null)),r.a.createElement(it,null),r.a.createElement(tt,null),r.a.createElement(ot,null),r.a.createElement(ft,{files:h}),r.a.createElement(je,null))},kt=a(412),wt=a(222),Et=a.n(wt),yt=Object(te.a)((function(e){return{layout:Object(Q.a)({width:"auto",height:"100%"},e.breakpoints.up(600+2*e.spacing(2)),{width:600,marginLeft:"auto",marginRight:"auto"}),paper:Object(Q.a)({position:"relative",display:"flex",flexDirection:"column",padding:e.spacing(2),height:"100%"},e.breakpoints.up(600+2*e.spacing(2)),{marginTop:e.spacing(6),marginBottom:e.spacing(6),padding:e.spacing(3),height:600}),copyright:{display:"flex",alignItems:"center"},backdrop:{zIndex:e.zIndex.drawer+1,color:"#fff"},minidiscLogo:{width:48}}})),xt=Object(ae.a)({palette:{type:"dark",primary:{light:"#6ec6ff",main:"#2196f3",dark:"#0069c0",contrastText:"#fff"}}}),jt=Object(ae.a)({palette:{type:"light"}}),Ot=function(){var e=yt(),t=Object(o.c)(),a=V((function(e){return e.appState})),n=a.mainView,i=a.loading,c=a.darkMode;return r.a.createElement(r.a.Fragment,null,r.a.createElement(ne.a,{theme:c?xt:jt},r.a.createElement(X.a,null),r.a.createElement("main",{className:e.layout},r.a.createElement(kt.a,{className:e.paper},"WELCOME"===n?r.a.createElement(Le,null):null,"MAIN"===n?r.a.createElement(vt,null):null,r.a.createElement(be.a,{className:e.copyright},r.a.createElement(Oe.a,{onClick:function(){return t(J.setDarkMode(!c))}},r.a.createElement(Et.a,{color:c?"secondary":void 0})),r.a.createElement(me.a,{variant:"body2",color:"textSecondary",style:{marginRight:"8px"}},"\xa9 ",r.a.createElement(ge.a,{rel:"noopener noreferrer",color:"inherit",target:"_blank",href:"https://stefano.brilli.me/"},"Stefano Brilli")," ",(new Date).getFullYear(),"."),r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://twitter.com/share?ref_src=twsrc%5Etfw",className:"twitter-share-button","data-via":"thecybercase","data-hashtags":"MiniDisc","data-dnt":"true","data-show-count":"false"},"Tweet"),r.a.createElement(be.a,{style:{flex:"1 1 auto"}})))),r.a.createElement(Z.a,{className:e.backdrop,open:i},r.a.createElement(ee.a,{color:"inherit"}))))},Ct=(a(391),a(143)),Nt=a(2),St=function(){function e(t){Object(f.a)(this,e),this.worker=t,this.messageCallback=void 0,t.onmessage=this.handleMessage.bind(this)}return Object(d.a)(e,[{key:"init",value:function(){var e=Object(m.a)(p.a.mark((function e(){var t=this;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,new Promise((function(e){t.messageCallback=e,t.worker.postMessage({action:"init"})}));case 2:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()},{key:"encode",value:function(){var e=Object(m.a)(p.a.mark((function e(t,a){var n,r=this;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,new Promise((function(e){r.messageCallback=e,r.worker.postMessage({action:"encode",bitrate:a,data:t},[t])}));case 2:return n=e.sent,e.abrupt("return",n.data.result);case 4:case"end":return e.stop()}}),e)})));return function(t,a){return e.apply(this,arguments)}}()},{key:"handleMessage",value:function(e){this.messageCallback(e),this.messageCallback=void 0}}]),e}();"undefined"!==typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&(onmessage=function(){var e=Object(m.a)(p.a.mark((function e(t){var a,n,r,i,c,o,l,s,u,m,f;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:a=t.data,n=a.action,r=Object(Nt.a)(a,["action"]),"init"===n?(self.importScripts(R("atracdenc.js")),self.Module().then((function(e){ue=e,self.postMessage({action:"init"}),ue.setLogger&&ue.setLogger((function(e,t){return console.log("".concat(t,": ").concat(e))}))}))):"encode"===n&&(i=r.bitrate,c=r.data,"inWavFile.wav","outAt3File.aea",o=new Uint8Array(c),ue.FS.writeFile("".concat("inWavFile.wav"),o),ue.callMain(["-e","atrac3","-i","inWavFile.wav","-o","outAt3File.aea","--bitrate",i]),l=ue.FS.stat("outAt3File.aea"),s=l.size,u=new Uint8Array(s-96),m=ue.FS.open("outAt3File.aea","r"),ue.FS.read(m,u,0,u.length,96),ue.FS.close(m),f=u.buffer,self.postMessage({action:"encode",result:f},[f]),self.close());case 2:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}());var Pt=a(410),Dt=function(){function e(){Object(f.a)(this,e),this.ffmpegProcess=void 0,this.atracdencProcess=void 0,this.loglines=[],this.inFileName="",this.outFileNameNoExt=""}return Object(d.a)(e,[{key:"init",value:function(){var e=Object(m.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:Object(Ct.setLogging)(!0);case 1:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()},{key:"prepare",value:function(){var e=Object(m.a)(p.a.mark((function e(t){var a,n=this;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return this.loglines=[],this.ffmpegProcess=Object(Ct.createWorker)({logger:function(e){n.loglines.push(e),console.log(e.action,e.message)},corePath:R("ffmpeg-core.js"),workerPath:R("worker.min.js")}),e.next=4,this.ffmpegProcess.load();case 4:return this.atracdencProcess=new St(new Pt),e.next=7,this.atracdencProcess.init();case 7:if(0!==(a=t.name.split(".").slice(-1)).length){e.next=10;break}throw new Error("Unrecognized file format: ".concat(t.name));case 10:return this.inFileName="inAudioFile.".concat(a[0]),this.outFileNameNoExt="outAudioFile",e.next=14,this.ffmpegProcess.write(this.inFileName,t);case 14:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}()},{key:"info",value:function(){var e=Object(m.a)(p.a.mark((function e(){var t,a,n,r,i,c,o,l,s,u,m;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.ffmpegProcess.transcode(this.inFileName,"".concat(this.outFileNameNoExt,".metadata"),"-f ffmetadata");case 2:t=/Audio:\s(.*?),/,a=/Input #0,\s(.*?),/,n=null,r=null,i=!0,c=!1,o=void 0,e.prev=9,l=this.loglines[Symbol.iterator]();case 11:if(i=(s=l.next()).done){e.next=26;break}if(u=s.value,null===(m=u.message.match(t))){e.next=17;break}return n=m[1],e.abrupt("continue",23);case 17:if(null===(m=u.message.match(a))){e.next=21;break}return r=m[1],e.abrupt("continue",23);case 21:if(null===n||null===r){e.next=23;break}return e.abrupt("break",26);case 23:i=!0,e.next=11;break;case 26:e.next=32;break;case 28:e.prev=28,e.t0=e.catch(9),c=!0,o=e.t0;case 32:e.prev=32,e.prev=33,i||null==l.return||l.return();case 35:if(e.prev=35,!c){e.next=38;break}throw o;case 38:return e.finish(35);case 39:return e.finish(32);case 40:return e.abrupt("return",{format:n,input:r});case 41:case"end":return e.stop()}}),e,this,[[9,28,32,40],[33,,35,39]])})));return function(){return e.apply(this,arguments)}}()},{key:"export",value:function(){var e=Object(m.a)(p.a.mark((function e(t){var a,n,r,i,c,o,l,s,u;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if("SP"!==(a=t.format)){e.next=12;break}return n="".concat(this.outFileNameNoExt,".raw"),e.next=5,this.ffmpegProcess.transcode(this.inFileName,n,"-f s16be -ar 44100");case 5:return e.next=7,this.ffmpegProcess.read(n);case 7:return r=e.sent,i=r.data,e.abrupt("return",i.buffer);case 12:return c="".concat(this.outFileNameNoExt,".wav"),e.next=15,this.ffmpegProcess.transcode(this.inFileName,c,"-f wav -ar 44100");case 15:return e.next=17,this.ffmpegProcess.read(c);case 17:o=e.sent,l=o.data,s="0",e.t0=a,e.next="LP2"===e.t0?23:"LP105"===e.t0?25:"LP4"===e.t0?27:29;break;case 23:return s="128",e.abrupt("break",29);case 25:return s="102",e.abrupt("break",29);case 27:return s="64",e.abrupt("break",29);case 29:return e.next=31,this.atracdencProcess.encode(l.buffer,s);case 31:return u=e.sent,e.abrupt("return",u);case 33:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}()}]),e}();k.netmdService=new v,k.audioExportService=new Dt,window.addEventListener("beforeunload",(function(e){$.getState().uploadDialog.visible&&(e.preventDefault(),e.returnValue="Warning! Recording will be interrupted")})),navigator&&navigator.usb?navigator.usb.ondisconnect=function(){$.dispatch(J.setState("WELCOME"))}:$.dispatch(J.setBrowserSupported(!1)),window.addEventListener("beforeinstallprompt",(function(e){e.preventDefault()})),c.a.render(r.a.createElement(o.a,{store:$},r.a.createElement(Ot,null)),document.getElementById("root")),function(e){if("serviceWorker"in navigator){if(new URL("/webminidisc",window.location.href).origin!==window.location.origin)return;window.addEventListener("load",(function(){var t="".concat("/webminidisc","/custom-service-worker.js");l?(!function(e,t){fetch(e,{headers:{"Service-Worker":"script"}}).then((function(a){var n=a.headers.get("content-type");404===a.status||null!=n&&-1===n.indexOf("javascript")?navigator.serviceWorker.ready.then((function(e){e.unregister().then((function(){window.location.reload()}))})):s(e,t)})).catch((function(){console.log("No internet connection found. App is running in offline mode.")}))}(t,e),navigator.serviceWorker.ready.then((function(){console.log("This web app is being served cache-first by a service worker. To learn more, visit https://bit.ly/CRA-PWA")}))):s(t,e)}))}}()}},[[241,1,2]]]); -//# sourceMappingURL=main.79696204.chunk.js.map \ No newline at end of file +(this.webpackJsonpwebmd=this.webpackJsonpwebmd||[]).push([[0],{215:function(e,t,a){e.exports=a.p+"static/media/chrome-icon.f3b6c54c.svg"},241:function(e,t,a){e.exports=a(411)},257:function(e,t){},259:function(e,t){},292:function(e,t){},293:function(e,t){},391:function(e,t,a){},410:function(e,t,a){e.exports=function(){return new Worker(a.p+"cc43d050d6e858b79f86.worker.js")}},411:function(e,t,a){"use strict";a.r(t);var n=a(0),r=a.n(n),i=a(15),c=a.n(i),o=a(17),l=Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));function s(e,t){navigator.serviceWorker.register(e).then((function(e){e.onupdatefound=function(){var a=e.installing;null!=a&&(a.onstatechange=function(){console.log("state change",a.state),"installed"===a.state&&(navigator.serviceWorker.controller?(console.log("New content is available and will be used when all tabs for this page are closed. See https://bit.ly/CRA-PWA."),t&&t.onUpdate&&t.onUpdate(e)):(console.log("Content is cached for offline use."),t&&t.onSuccess&&t.onSuccess(e)))})},e.update()})).catch((function(e){console.error("Error during service worker registration:",e)}))}var u=a(6),p=a.n(u),f=a(16),m=a(43),d=a(30),b=a(20),g=a(211),h=a(359),v=function(){function e(){Object(m.a)(this,e),this.netmdInterface=void 0}return Object(d.a)(e,[{key:"pair",value:function(){var e=Object(f.a)(p.a.mark((function e(){var t;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Object(b.openNewDevice)(navigator.usb);case 2:if(null!==(t=e.sent)){e.next=5;break}return e.abrupt("return",!1);case 5:return this.netmdInterface=t,e.abrupt("return",!0);case 7:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"connect",value:function(){var e=Object(f.a)(p.a.mark((function e(){var t;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Object(b.openPairedDevice)(navigator.usb);case 2:if(null!==(t=e.sent)){e.next=5;break}return e.abrupt("return",!1);case 5:return this.netmdInterface=t,e.abrupt("return",!0);case 7:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"listContent",value:function(){var e=Object(f.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,Object(b.listContent)(this.netmdInterface);case 2:return e.abrupt("return",e.sent);case 3:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"getDeviceName",value:function(){var e=Object(f.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.netMd.getDeviceName();case 2:return e.abrupt("return",e.sent);case 3:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"finalize",value:function(){var e=Object(f.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.netMd.finalize();case 2:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"renameTrack",value:function(){var e=Object(f.a)(p.a.mark((function e(t,a){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.setTrackTitle(t,a);case 2:case"end":return e.stop()}}),e,this)})));return function(t,a){return e.apply(this,arguments)}}()},{key:"deleteTrack",value:function(){var e=Object(f.a)(p.a.mark((function e(t){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.eraseTrack(t);case 2:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}()},{key:"wipeDisc",value:function(){var e=Object(f.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.netmdInterface.eraseDisc();case 2:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"upload",value:function(){var e=Object(f.a)(p.a.mark((function e(t,a,n,r){var i,c,o,l,s,u,f;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return l=function(){r({written:c,encrypted:o,total:i})},i=a.byteLength,c=0,o=0,s=new h,u=Object(g.makeGetAsyncPacketIteratorOnWorkerThread)(s,(function(e){var t=e.encryptedBytes;o=t,l()})),f=new b.MDTrack(t,n,a,524288,u),e.next=9,Object(b.download)(this.netmdInterface,f,(function(e){var t=e.writtenBytes;c=t,l()}));case 9:case"end":return e.stop()}}),e,this)})));return function(t,a,n,r){return e.apply(this,arguments)}}()}]),e}(),k={},w=a(24),E=a(28),y=a(19),x=Object(E.b)({name:"uploadDialog",initialState:{visible:!1,writtenProgress:0,encryptedProgress:0,totalProgress:1,trackTotal:1,trackConverting:0,trackCurrent:0,titleCurrent:"",titleConverting:""},reducers:{setVisible:function(e,t){e.visible=t.payload},setWriteProgress:function(e,t){e.encryptedProgress=t.payload.encrypted,e.writtenProgress=t.payload.written,e.totalProgress=t.payload.total},setTrackProgress:function(e,t){e.trackTotal=t.payload.total,e.trackCurrent=t.payload.current,e.trackConverting=t.payload.converting,e.titleCurrent=t.payload.titleCurrent,e.titleConverting=t.payload.titleConverting}}}),j=x.reducer,O=x.actions,C=Object(y.enableBatching)(j),N=Object(E.b)({name:"renameDialog",initialState:{visible:!1,title:"",index:-1},reducers:{setVisible:function(e,t){e.visible=t.payload},setCurrentName:function(e,t){e.title=t.payload},setIndex:function(e,t){e.index=t.payload}}}),S=N.reducer,P=N.actions,D=Object(y.enableBatching)(S),F=Object(E.b)({name:"errorDialog",initialState:{visible:!1,error:""},reducers:{setVisible:function(e,t){e.visible=t.payload},setErrorMessage:function(e,t){e.error="".concat(t.payload)}}}),M=F.actions,W=F.reducer,L=Object(y.enableBatching)(W),T=Object(E.b)({name:"convertDialog",initialState:{visible:!1,format:"LP2"},reducers:{setVisible:function(e,t){e.visible=t.payload},setFormat:function(e,t){e.format=t.payload}}}),A=T.actions,B=T.reducer,I=Object(y.enableBatching)(B);function V(e){return Object(o.d)(e,o.b)}function R(e){return"".concat("/webminidisc","/").concat(e)}var _={mainView:"WELCOME",loading:!1,pairingFailed:!1,pairingMessage:"",browserSupported:!0,darkMode:function(e,t){var a=localStorage.getItem(e);if(null===a)return t;try{return JSON.parse(a)}catch(n){return t}}("darkMode",!1),aboutDialogVisible:!1},U=Object(E.b)({name:"app",initialState:_,reducers:{setState:function(e,t){e.mainView=t.payload},setLoading:function(e,t){e.loading=t.payload},setPairingFailed:function(e,t){e.pairingFailed=t.payload},setPairingMessage:function(e,t){e.pairingMessage=t.payload},setBrowserSupported:function(e,t){e.browserSupported=t.payload},setDarkMode:function(e,t){var a,n;e.darkMode=t.payload,a="darkMode",n=e.darkMode,localStorage.setItem(a,JSON.stringify(n))},showAboutDialog:function(e,t){e.aboutDialogVisible=t.payload}}}),z=U.reducer,J=U.actions,G=Object(y.enableBatching)(z),H=Object(E.b)({name:"main",initialState:{disc:null,deviceName:""},reducers:{setDisc:function(e,t){e.disc=t.payload},setDeviceName:function(e,t){e.deviceName=t.payload}}}),Y=H.reducer,q=H.actions,K=Object(y.enableBatching)(Y),$=Object(E.a)({reducer:{renameDialog:D,uploadDialog:C,errorDialog:L,convertDialog:I,appState:G,main:K},middleware:Object(w.a)(Object(E.c)())}),Q=a(11),X=a(474),Z=a(416),ee=a(475),te=a(462),ae=a(223),ne=a(466),re=a(27),ie=(a(365),a(226)),ce=a(213);function oe(){return function(){var e=Object(f.a)(p.a.mark((function e(t){var a,n;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t(J.setLoading(!0)),e.next=3,k.netmdService.listContent();case 3:return a=e.sent,e.next=6,k.netmdService.getDeviceName();case 6:n=e.sent,t(Object(y.batchActions)([q.setDisc(a),q.setDeviceName(n),J.setLoading(!1)]));case 8:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()}var le={SP:b.Wireformat.pcm,LP2:b.Wireformat.lp2,LP105:b.Wireformat.l105kbps,LP4:b.Wireformat.lp4};var se,ue,pe=a(459),fe=a(145),me=a(417),de=a(418),be=a(476),ge=a(457),he=a(451),ve=a(458),ke=a(455),we=a(456),Ee=a(454),ye=a(450),xe=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),je=function(e){var t=Object(o.c)(),a=V((function(e){return e.appState.aboutDialogVisible}));return r.a.createElement(he.a,{open:a,maxWidth:"sm",fullWidth:!0,TransitionComponent:xe,"aria-labelledby":"about-dialog-slide-title"},r.a.createElement(Ee.a,{id:"about-dialog-slide-title"},"About Web MiniDisc"),r.a.createElement(ke.a,null,r.a.createElement(we.a,null,"Web MiniDisc has been made possible by"),r.a.createElement("ul",null,r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://www.ffmpeg.org/",target:"_blank"},"FFmpeg")," ","and"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/ffmpegjs/FFmpeg",target:"_blank"},"ffmpegjs"),", to read your audio files (wav, mp3, ogg, mp4, etc...)."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/dcherednik/atracdenc/",target:"_blank"},"Atracdenc"),", to support atrac3 encoding (lp2, lp4 audio formats)."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://emscripten.org/",target:"_blank"},"Emscripten"),", to run both FFmpeg and Atracdenc in the browser."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/cybercase/netmd-js",target:"_blank"},"netmd-js"),", to send commands to NetMD devices using Javascript."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/glaubitz/linux-minidisc",target:"_blank"},"linux-minidisc"),", to make the netmd-js project possible."),r.a.createElement("li",null,r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://material-ui.com/",target:"_blank"},"material-ui"),", to build the user interface.")),r.a.createElement(we.a,null,"Attribution"),r.a.createElement("ul",null,r.a.createElement("li",null,"MiniDisc logo from"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://en.wikipedia.org/wiki/MiniDisc",target:"_blank"},"https://en.wikipedia.org/wiki/MiniDisc")),r.a.createElement("li",null,"MiniDisc icon from"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://www.deviantart.com/blinkybill/art/Sony-MiniDisc-Plastic-Icon-473812540",target:"_blank"},"http://fav.me/d7u3g3g")))),r.a.createElement(ve.a,null,r.a.createElement(pe.a,{onClick:function(){t(J.showAboutDialog(!1))}},"Close")))},Oe=a(460),Ce=a(225),Ne=a(479),Se=a(214),Pe=a.n(Se),De=function(){var e=Object(o.c)(),t=V((function(e){return e.appState})).mainView,a=r.a.useState(null),n=Object(re.a)(a,2),i=n[0],c=n[1],l=Boolean(i),s=function(){c(null)},u=[];return"MAIN"===t&&(u.push(r.a.createElement(Ne.a,{key:"update",onClick:function(){e(oe()),s()}},"Refresh")),u.push(r.a.createElement(Ne.a,{key:"wipe",onClick:function(){e(function(){var e=Object(f.a)(p.a.mark((function e(t){var a;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=k.netmdService,t(J.setLoading(!0)),e.next=4,a.wipeDisc();case 4:oe()(t);case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),s()}},"Wipe Disc")),u.push(r.a.createElement(Ne.a,{key:"exit",onClick:function(){e(J.setState("WELCOME")),s()}},"Exit"))),u.push(r.a.createElement(Ne.a,{key:"about",onClick:function(){e(J.showAboutDialog(!0)),s()}},"About")),u.push(r.a.createElement(Ne.a,{key:"github",onClick:s},r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://github.com/cybercase/webminidisc",target:"_blank"},"Fork me on GitHub"))),r.a.createElement(r.a.Fragment,null,r.a.createElement(Oe.a,{"aria-label":"actions","aria-controls":"actions-menu","aria-haspopup":"true",onClick:function(e){c(e.currentTarget)}},r.a.createElement(Pe.a,null)),r.a.createElement(Ce.a,{id:"actions-menu",anchorEl:i,keepMounted:!0,open:l,onClose:s},u))},Fe=a(215),Me=a.n(Fe),We=Object(te.a)((function(e){return{main:{position:"relative",flex:"1 1 auto",display:"flex",justifyContent:"center",flexDirection:"column",alignItems:"center"},button:{marginTop:e.spacing(3),minWidth:150},spacing:{marginTop:e.spacing(1)},chromeLogo:{marginTop:e.spacing(1),width:96,height:96},why:{alignSelf:"flex-start",marginTop:e.spacing(3)},headBox:{display:"flex",justifyContent:"space-between"}}})),Le=function(e){var t=We(),a=Object(o.c)(),i=V((function(e){return e.appState})),c=i.browserSupported,l=i.pairingFailed,s=i.pairingMessage;s.toLowerCase().match(/denied/);var u=Object(n.useState)(!1),m=Object(re.a)(u,2),d=m[0],b=m[1];return r.a.createElement(r.a.Fragment,null,r.a.createElement(be.a,{className:t.headBox},r.a.createElement(fe.a,{component:"h1",variant:"h4"},"Web MiniDisc"),r.a.createElement(De,null)),r.a.createElement(fe.a,{component:"h2",variant:"body2"},"Brings NetMD Devices to the Web"),r.a.createElement(be.a,{className:t.main},c?r.a.createElement(r.a.Fragment,null,r.a.createElement(fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"Press the button to connect to a NetMD device"),r.a.createElement(pe.a,{variant:"contained",color:"primary",onClick:function(){return a(function(){var e=Object(f.a)(p.a.mark((function e(t,a){var n;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t(J.setPairingFailed(!1)),e.next=3,k.audioExportService.init();case 3:return e.prev=3,e.next=6,k.netmdService.connect();case 6:if(!e.sent){e.next=10;break}return t(J.setState("MAIN")),e.abrupt("return");case 10:e.next=15;break;case 12:e.prev=12,e.t0=e.catch(3),console.error(e.t0);case 15:return e.prev=15,e.next=18,k.netmdService.pair();case 18:if(!e.sent){e.next=22;break}return t(J.setState("MAIN")),e.abrupt("return");case 22:t(Object(y.batchActions)([J.setPairingMessage("Connection Failed"),J.setPairingFailed(!0)])),e.next=30;break;case 25:e.prev=25,e.t1=e.catch(15),console.error(e.t1),n=e.t1.message,t(Object(y.batchActions)([J.setPairingMessage(n),J.setPairingFailed(!0)]));case 30:case"end":return e.stop()}}),e,null,[[3,12],[15,25]])})));return function(t,a){return e.apply(this,arguments)}}())},className:t.button},"Connect"),r.a.createElement(me.a,{error:!0,className:t.spacing,style:{visibility:l?"visible":"hidden"}},r.a.createElement(de.a,null,s))):r.a.createElement(r.a.Fragment,null,r.a.createElement(fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"This Web browser is not supported.\xa0",r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"#",onClick:function(e){e.preventDefault(),b(!0)}},"Learn Why")),r.a.createElement(ge.a,{rel:"noopener noreferrer",target:"_blank",href:"https://www.google.com/chrome/"},r.a.createElement("img",{alt:"Chrome Logo",src:Me.a,className:t.chromeLogo})),r.a.createElement(fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"Try using"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",target:"_blank",href:"https://www.google.com/chrome/"},"Chrome")," ","instead"),d?r.a.createElement(r.a.Fragment,null,r.a.createElement(fe.a,{component:"p",variant:"body2",className:t.why},"Web MiniDisc requires a browser that supports both"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",target:"_blank",href:"https://wicg.github.io/webusb/"},"WebUSB")," ","and"," ",r.a.createElement(ge.a,{rel:"noopener noreferrer",target:"_blank",href:"https://webassembly.org/"},"WebAssembly"),"."),r.a.createElement("ul",null,r.a.createElement("li",null,"WebUSB is needed to control the NetMD device via the USB connection to your computer."),r.a.createElement("li",null,"WebAssembly is used to convert the music to a MiniDisc compatible format"))):null)),r.a.createElement(je,null))},Te=a(216),Ae=a(3),Be=a(224),Ie=a(14),Ve=a(473),Re=a(221),_e=a.n(Re),Ue=a(219),ze=a.n(Ue),Je=a(220),Ge=a.n(Je),He=a(468),Ye=a(472),qe=a(471),Ke=a(469),$e=a(470),Qe=a(467),Xe=a(478),Ze=a(464),et=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),tt=function(e){var t=Object(o.c)(),a=V((function(e){return e.renameDialog.visible})),n=V((function(e){return e.renameDialog.title})),i=V((function(e){return e.renameDialog.index})),c=function(){t(P.setVisible(!1))},l=function(){t(function(e){var t=e.index,a=e.newName;return(function(){var e=Object(f.a)(p.a.mark((function e(n){var r;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=k.netmdService,e.next=3,r.renameTrack(t,a);case 3:n(P.setVisible(!1)),oe()(n);case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}())}({index:i,newName:n}))};return r.a.createElement(he.a,{open:a,onClose:c,maxWidth:"sm",fullWidth:!0,TransitionComponent:et,"aria-labelledby":"rename-dialog-title"},r.a.createElement(Ee.a,{id:"rename-dialog-title"},"Rename Track"),r.a.createElement(ke.a,null,r.a.createElement(Ze.a,{autoFocus:!0,id:"name",label:"Track Name",type:"text",fullWidth:!0,value:n,onKeyDown:function(e){"Enter"===e.key&&l()},onChange:function(e){t(P.setCurrentName(e.target.value))}})),r.a.createElement(ve.a,null,r.a.createElement(pe.a,{onClick:c},"Cancel"),r.a.createElement(pe.a,{color:"primary",onClick:l},"Rename")))},at=a(465),nt=Object(te.a)((function(e){return{progressPerc:{marginTop:e.spacing(1)},progressBar:{marginTop:e.spacing(3)},uploadLabel:{marginTop:e.spacing(3)}}})),rt=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),it=function(e){var t=nt(),a=V((function(e){return e.uploadDialog})),n=a.visible,i=a.writtenProgress,c=a.encryptedProgress,o=a.totalProgress,l=a.trackTotal,s=a.trackCurrent,u=a.trackConverting,p=a.titleCurrent,f=a.titleConverting,m=Math.floor(i/o*100),d=Math.floor(c/o*100),b=Math.floor(u/l*100);return r.a.createElement(he.a,{open:n,maxWidth:"sm",fullWidth:!0,TransitionComponent:rt,"aria-labelledby":"alert-dialog-slide-title","aria-describedby":"alert-dialog-slide-description"},r.a.createElement(Ee.a,{id:"alert-dialog-slide-title"},"Recording..."),r.a.createElement(ke.a,null,r.a.createElement(we.a,{id:"alert-dialog-slide-description"},100===b&&u===l?"Conversion completed":"Converting ".concat(u+1," of ").concat(l,": ").concat(f)),r.a.createElement(at.a,{className:t.progressBar,variant:0===b?"indeterminate":"determinate",color:"primary",value:b}),r.a.createElement(be.a,{className:t.progressPerc},b,"%"),r.a.createElement(we.a,{id:"alert-dialog-slide-description",className:t.uploadLabel},"Uploading ",s," of ",l,": ",p),r.a.createElement(at.a,{className:t.progressBar,variant:"buffer",color:"secondary",value:m,valueBuffer:d}),r.a.createElement(be.a,{className:t.progressPerc},m,"%")),r.a.createElement(ve.a,null))},ct=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),ot=function(e){var t=Object(o.c)(),a=V((function(e){return e.errorDialog})),n=a.visible,i=a.error;return r.a.createElement(he.a,{open:n,maxWidth:"sm",fullWidth:!0,TransitionComponent:ct,"aria-labelledby":"error-dialog-slide-title","aria-describedby":"error-dialog-slide-description"},r.a.createElement(Ee.a,{id:"alert-dialog-slide-title"},"Error"),r.a.createElement(ke.a,null,r.a.createElement(we.a,{id:"alert-dialog-slide-description"},i)),r.a.createElement(ve.a,null,r.a.createElement(pe.a,{onClick:function(){t(M.setVisible(!1))}},"Close")))},lt=a(423),st=a(421),ut=a(419),pt=r.a.forwardRef((function(e,t){return r.a.createElement(ye.a,Object.assign({direction:"up",ref:t},e))})),ft=Object(te.a)((function(e){return{container:{display:"flex",flexDirection:"row"},formControl:{minWidth:120}}})),mt=function(e){var t=Object(o.c)(),a=ft(),n=V((function(e){return e.convertDialog})),i=n.visible,c=n.format,l=function(){t(A.setVisible(!1))};return r.a.createElement(he.a,{open:i,maxWidth:"xs",fullWidth:!0,TransitionComponent:pt,"aria-labelledby":"convert-dialog-slide-title","aria-describedby":"convert-dialog-slide-description"},r.a.createElement(Ee.a,{id:"convert-dialog-slide-title"},"Upload Settings"),r.a.createElement(ke.a,null,r.a.createElement(me.a,{className:a.formControl},r.a.createElement(lt.a,{color:"secondary",id:"convert-dialog-format"},"Format"),r.a.createElement(st.a,{labelId:"convert-dialog-format-label",id:"convert-dialog-format",value:c,color:"secondary",onChange:function(e){t(A.setFormat(e.target.value))},input:r.a.createElement(ut.a,null)},r.a.createElement(Ne.a,{value:"SP"},"SP"),r.a.createElement(Ne.a,{value:"LP2"},"LP2"),r.a.createElement(Ne.a,{value:"LP4"},"LP4")))),r.a.createElement(ve.a,null,r.a.createElement(pe.a,{onClick:l},"Cancel"),r.a.createElement(pe.a,{onClick:function(){l(),t(function(e,t){return function(){var a=Object(f.a)(p.a.mark((function a(n,r){var i,c,o,l,s,u,m,d,b,g,h,v,w,E,x,j,C,N,S,P;return p.a.wrap((function(a){for(;;)switch(a.prev=a.next){case 0:i=k.audioExportService,c=k.netmdService,o=le[t],n(O.setVisible(!0)),l=function(e){var t=e.written,a=e.encrypted,r=e.total;n(O.setWriteProgress({written:t,encrypted:a,total:r}))},s={current:0,converting:0,total:e.length,titleCurrent:"",titleConverting:""},u=function(){n(O.setTrackProgress(s))},m=function(){var e=Object(ie.a)(p.a.mark((function e(a){var n,r,c,o;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:c=function(){if(r===a.length)return s.converting=r,s.titleConverting="",void u();var e=a[r];s.converting=r,s.titleConverting=e.name,u(),r++,n.push(new Promise(function(){var a=Object(f.a)(p.a.mark((function a(n,r){var o;return p.a.wrap((function(a){for(;;)switch(a.prev=a.next){case 0:return a.prev=0,a.next=3,i.prepare(e);case 3:return a.next=5,i.export({format:t});case 5:o=a.sent,c(),n({file:e,data:o}),a.next=15;break;case 10:a.prev=10,a.t0=a.catch(0),d=a.t0,b="".concat(e.name,": Unsupported or unrecognized format"),r(a.t0);case 15:case"end":return a.stop()}}),a,null,[[0,10]])})));return function(e,t){return a.apply(this,arguments)}}()))},n=[],r=0,c(),o=0;case 5:if(!(o0))},m>0?r.a.createElement(dt.a,{indeterminate:m>0&&m0,onChange:function(e){s.length0?r.a.createElement(fe.a,{className:S.toolbarLabel,color:"inherit",variant:"subtitle1"},m," selected"):r.a.createElement(fe.a,{component:"h3",variant:"h6",className:S.toolbarLabel},"Content"),m>0?r.a.createElement(Xe.a,{title:"Delete"},r.a.createElement(Oe.a,{"aria-label":"delete",onClick:function(e){var a;t((a=s,function(){var e=Object(f.a)(p.a.mark((function e(t){var n,r,i,c,o,l,s;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:n=k.netmdService,t(J.setLoading(!0)),(a=a.sort()).reverse(),r=!0,i=!1,c=void 0,e.prev=7,o=a[Symbol.iterator]();case 9:if(r=(l=o.next()).done){e.next=16;break}return s=l.value,e.next=13,n.deleteTrack(s);case 13:r=!0,e.next=9;break;case 16:e.next=22;break;case 18:e.prev=18,e.t0=e.catch(7),i=!0,c=e.t0;case 22:e.prev=22,e.prev=23,r||null==o.return||o.return();case 25:if(e.prev=25,!i){e.next=28;break}throw c;case 28:return e.finish(25);case 29:return e.finish(22);case 30:oe()(t);case 31:case"end":return e.stop()}}),e,null,[[7,18,22,30],[23,,25,29]])})));return function(t){return e.apply(this,arguments)}}()))}},r.a.createElement(ze.a,null))):null,m>0?r.a.createElement(Xe.a,{title:"Rename"},r.a.createElement(Oe.a,{"aria-label":"rename",disabled:1!==m,onClick:function(e){q(0,s[0])}},r.a.createElement(Ge.a,null))):null),r.a.createElement(be.a,Object.assign({className:S.main},j()),r.a.createElement("input",O()),r.a.createElement(He.a,{size:"small"},r.a.createElement(Ke.a,null,r.a.createElement($e.a,null,r.a.createElement(qe.a,null,"Title"),r.a.createElement(qe.a,null,"Format"),r.a.createElement(qe.a,{align:"right"},"Duration"))),r.a.createElement(Ye.a,null,D.map((function(e){return r.a.createElement($e.a,{hover:!0,selected:s.includes(e.index),key:e.index,onDoubleClick:function(t){return q(0,e.index)},onClick:function(t){return a=e.index,void(s.includes(a)?u(s.filter((function(e){return e!==a}))):u([].concat(Object(w.a)(s),[a])));var a}},r.a.createElement(qe.a,{className:S.titleCell,title:e.title},e.title||"No Title"),r.a.createElement(qe.a,null,r.a.createElement("span",{className:S.formatBadge},e.encoding)),r.a.createElement(qe.a,{align:"right"},e.duration))})))),r.a.createElement(Z.a,{className:S.backdrop,open:C},"Drop your Music to Upload")),r.a.createElement(Ve.a,{color:"primary","aria-label":"add",className:S.add,onClick:N},r.a.createElement(_e.a,null)),r.a.createElement(it,null),r.a.createElement(tt,null),r.a.createElement(ot,null),r.a.createElement(mt,{files:h}),r.a.createElement(je,null))},kt=a(412),wt=a(222),Et=a.n(wt),yt=Object(te.a)((function(e){return{layout:Object(Q.a)({width:"auto",height:"100%"},e.breakpoints.up(600+2*e.spacing(2)),{width:600,marginLeft:"auto",marginRight:"auto"}),paper:Object(Q.a)({position:"relative",display:"flex",flexDirection:"column",padding:e.spacing(2),height:"100%"},e.breakpoints.up(600+2*e.spacing(2)),{marginTop:e.spacing(6),marginBottom:e.spacing(6),padding:e.spacing(3),height:600}),copyright:{display:"flex",alignItems:"center"},backdrop:{zIndex:e.zIndex.drawer+1,color:"#fff"},minidiscLogo:{width:48}}})),xt=Object(ae.a)({palette:{type:"dark",primary:{light:"#6ec6ff",main:"#2196f3",dark:"#0069c0",contrastText:"#fff"}}}),jt=Object(ae.a)({palette:{type:"light"}}),Ot=function(){var e=yt(),t=Object(o.c)(),a=V((function(e){return e.appState})),n=a.mainView,i=a.loading,c=a.darkMode;return r.a.createElement(r.a.Fragment,null,r.a.createElement(ne.a,{theme:c?xt:jt},r.a.createElement(X.a,null),r.a.createElement("main",{className:e.layout},r.a.createElement(kt.a,{className:e.paper},"WELCOME"===n?r.a.createElement(Le,null):null,"MAIN"===n?r.a.createElement(vt,null):null,r.a.createElement(be.a,{className:e.copyright},r.a.createElement(Oe.a,{onClick:function(){return t(J.setDarkMode(!c))}},r.a.createElement(Et.a,{color:c?"secondary":void 0})),r.a.createElement(fe.a,{variant:"body2",color:"textSecondary",style:{marginRight:"8px"}},"\xa9 ",r.a.createElement(ge.a,{rel:"noopener noreferrer",color:"inherit",target:"_blank",href:"https://stefano.brilli.me/"},"Stefano Brilli")," ",(new Date).getFullYear(),"."),r.a.createElement(ge.a,{rel:"noopener noreferrer",href:"https://twitter.com/share?ref_src=twsrc%5Etfw",className:"twitter-share-button","data-via":"thecybercase","data-hashtags":"MiniDisc","data-dnt":"true","data-show-count":"false"},"Tweet"),r.a.createElement(be.a,{style:{flex:"1 1 auto"}})))),r.a.createElement(Z.a,{className:e.backdrop,open:i},r.a.createElement(ee.a,{color:"inherit"}))))},Ct=(a(391),a(143)),Nt=a(2),St=function(){function e(t){Object(m.a)(this,e),this.worker=t,this.messageCallback=void 0,t.onmessage=this.handleMessage.bind(this)}return Object(d.a)(e,[{key:"init",value:function(){var e=Object(f.a)(p.a.mark((function e(){var t=this;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,new Promise((function(e){t.messageCallback=e,t.worker.postMessage({action:"init"})}));case 2:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()},{key:"encode",value:function(){var e=Object(f.a)(p.a.mark((function e(t,a){var n,r=this;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,new Promise((function(e){r.messageCallback=e,r.worker.postMessage({action:"encode",bitrate:a,data:t},[t])}));case 2:return n=e.sent,e.abrupt("return",n.data.result);case 4:case"end":return e.stop()}}),e)})));return function(t,a){return e.apply(this,arguments)}}()},{key:"handleMessage",value:function(e){this.messageCallback(e),this.messageCallback=void 0}}]),e}();"undefined"!==typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&(onmessage=function(){var e=Object(f.a)(p.a.mark((function e(t){var a,n,r,i,c,o,l,s,u,f,m;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:a=t.data,n=a.action,r=Object(Nt.a)(a,["action"]),"init"===n?(self.importScripts(R("atracdenc.js")),self.Module().then((function(e){ue=e,self.postMessage({action:"init"}),ue.setLogger&&ue.setLogger((function(e,t){return console.log("".concat(t,": ").concat(e))}))}))):"encode"===n&&(i=r.bitrate,c=r.data,"inWavFile.wav","outAt3File.aea",o=new Uint8Array(c),ue.FS.writeFile("".concat("inWavFile.wav"),o),ue.callMain(["-e","atrac3","-i","inWavFile.wav","-o","outAt3File.aea","--bitrate",i]),l=ue.FS.stat("outAt3File.aea"),s=l.size,u=new Uint8Array(s-96),f=ue.FS.open("outAt3File.aea","r"),ue.FS.read(f,u,0,u.length,96),ue.FS.close(f),m=u.buffer,self.postMessage({action:"encode",result:m},[m]),self.close());case 2:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}());var Pt=a(410),Dt=function(){function e(){Object(m.a)(this,e),this.ffmpegProcess=void 0,this.atracdencProcess=void 0,this.loglines=[],this.inFileName="",this.outFileNameNoExt=""}return Object(d.a)(e,[{key:"init",value:function(){var e=Object(f.a)(p.a.mark((function e(){return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:Object(Ct.setLogging)(!0);case 1:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}()},{key:"prepare",value:function(){var e=Object(f.a)(p.a.mark((function e(t){var a,n=this;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return this.loglines=[],this.ffmpegProcess=Object(Ct.createWorker)({logger:function(e){n.loglines.push(e),console.log(e.action,e.message)},corePath:R("ffmpeg-core.js"),workerPath:R("worker.min.js")}),e.next=4,this.ffmpegProcess.load();case 4:return this.atracdencProcess=new St(new Pt),e.next=7,this.atracdencProcess.init();case 7:if(0!==(a=t.name.split(".").slice(-1)).length){e.next=10;break}throw new Error("Unrecognized file format: ".concat(t.name));case 10:return this.inFileName="inAudioFile.".concat(a[0]),this.outFileNameNoExt="outAudioFile",e.next=14,this.ffmpegProcess.write(this.inFileName,t);case 14:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}()},{key:"info",value:function(){var e=Object(f.a)(p.a.mark((function e(){var t,a,n,r,i,c,o,l,s,u,f;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.ffmpegProcess.transcode(this.inFileName,"".concat(this.outFileNameNoExt,".metadata"),"-f ffmetadata");case 2:t=/Audio:\s(.*?),/,a=/Input #0,\s(.*?),/,n=null,r=null,i=!0,c=!1,o=void 0,e.prev=9,l=this.loglines[Symbol.iterator]();case 11:if(i=(s=l.next()).done){e.next=26;break}if(u=s.value,null===(f=u.message.match(t))){e.next=17;break}return n=f[1],e.abrupt("continue",23);case 17:if(null===(f=u.message.match(a))){e.next=21;break}return r=f[1],e.abrupt("continue",23);case 21:if(null===n||null===r){e.next=23;break}return e.abrupt("break",26);case 23:i=!0,e.next=11;break;case 26:e.next=32;break;case 28:e.prev=28,e.t0=e.catch(9),c=!0,o=e.t0;case 32:e.prev=32,e.prev=33,i||null==l.return||l.return();case 35:if(e.prev=35,!c){e.next=38;break}throw o;case 38:return e.finish(35);case 39:return e.finish(32);case 40:return e.abrupt("return",{format:n,input:r});case 41:case"end":return e.stop()}}),e,this,[[9,28,32,40],[33,,35,39]])})));return function(){return e.apply(this,arguments)}}()},{key:"export",value:function(){var e=Object(f.a)(p.a.mark((function e(t){var a,n,r,i,c,o,l,s,u;return p.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if("SP"!==(a=t.format)){e.next=12;break}return n="".concat(this.outFileNameNoExt,".raw"),e.next=5,this.ffmpegProcess.transcode(this.inFileName,n,"-f s16be -ar 44100");case 5:return e.next=7,this.ffmpegProcess.read(n);case 7:return r=e.sent,i=r.data,e.abrupt("return",i.buffer);case 12:return c="".concat(this.outFileNameNoExt,".wav"),e.next=15,this.ffmpegProcess.transcode(this.inFileName,c,"-f wav -ar 44100");case 15:return e.next=17,this.ffmpegProcess.read(c);case 17:o=e.sent,l=o.data,s="0",e.t0=a,e.next="LP2"===e.t0?23:"LP105"===e.t0?25:"LP4"===e.t0?27:29;break;case 23:return s="128",e.abrupt("break",29);case 25:return s="102",e.abrupt("break",29);case 27:return s="64",e.abrupt("break",29);case 29:return e.next=31,this.atracdencProcess.encode(l.buffer,s);case 31:return u=e.sent,e.abrupt("return",u);case 33:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}()}]),e}();k.netmdService=new v,k.audioExportService=new Dt,window.addEventListener("beforeunload",(function(e){$.getState().uploadDialog.visible&&(e.preventDefault(),e.returnValue="Warning! Recording will be interrupted")})),navigator&&navigator.usb?navigator.usb.ondisconnect=function(){$.dispatch(J.setState("WELCOME"))}:$.dispatch(J.setBrowserSupported(!1)),window.addEventListener("beforeinstallprompt",(function(e){e.preventDefault()})),c.a.render(r.a.createElement(o.a,{store:$},r.a.createElement(Ot,null)),document.getElementById("root")),function(e){if("serviceWorker"in navigator){if(new URL("/webminidisc",window.location.href).origin!==window.location.origin)return;window.addEventListener("load",(function(){var t="".concat("/webminidisc","/final-service-worker.js");l?(!function(e,t){fetch(e,{headers:{"Service-Worker":"script"}}).then((function(a){var n=a.headers.get("content-type");404===a.status||null!=n&&-1===n.indexOf("javascript")?navigator.serviceWorker.ready.then((function(e){e.unregister().then((function(){window.location.reload()}))})):s(e,t)})).catch((function(){console.log("No internet connection found. App is running in offline mode.")}))}(t,e),navigator.serviceWorker.ready.then((function(){console.log("This web app is being served cache-first by a service worker. To learn more, visit https://bit.ly/CRA-PWA")}))):s(t,e)}))}}()}},[[241,1,2]]]); +//# sourceMappingURL=main.a222d332.chunk.js.map \ No newline at end of file diff --git a/static/js/main.a222d332.chunk.js.map b/static/js/main.a222d332.chunk.js.map new file mode 100644 index 0000000..204b05f --- /dev/null +++ b/static/js/main.a222d332.chunk.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["images/chrome-icon.svg","webpack:///./src/services/atracdenc-worker.ts?dc3c","serviceWorker.ts","services/netmd.ts","services/registry.ts","redux/upload-dialog-feature.ts","redux/rename-dialog-feature.ts","redux/error-dialog-feature.ts","redux/convert-dialog-feature.ts","utils.ts","redux/app-feature.ts","redux/main-feature.ts","redux/store.ts","redux/actions.ts","services/atracdenc-worker.ts","components/about-dialog.tsx","components/topmenu.tsx","components/welcome.tsx","components/rename-dialog.tsx","components/upload-dialog.tsx","components/error-dialog.tsx","components/convert-dialog.tsx","components/main.tsx","components/app.tsx","services/audio-export.ts","index.tsx"],"names":["module","exports","Worker","isLocalhost","Boolean","window","location","hostname","match","registerValidSW","swUrl","config","navigator","serviceWorker","register","then","registration","onupdatefound","installingWorker","installing","onstatechange","console","log","state","controller","onUpdate","onSuccess","update","catch","error","require","NetMDUSBService","netmdInterface","openNewDevice","usb","iface","this","openPairedDevice","listContent","netMd","getDeviceName","finalize","index","newTitle","setTrackTitle","eraseTrack","eraseDisc","title","data","format","progressCallback","updateProgress","written","encrypted","total","byteLength","w","webWorkerAsyncPacketIterator","makeGetAsyncPacketIteratorOnWorkerThread","encryptedBytes","mdTrack","MDTrack","download","writtenBytes","ServiceRegistry","slice","createSlice","name","initialState","visible","writtenProgress","encryptedProgress","totalProgress","trackTotal","trackConverting","trackCurrent","titleCurrent","titleConverting","reducers","setVisible","action","payload","setWriteProgress","setTrackProgress","current","converting","reducer","actions","enableBatching","setCurrentName","setIndex","setErrorMessage","setFormat","useShallowEqualSelector","selector","useSelector","shallowEqual","getPublicPathFor","script","process","mainView","loading","pairingFailed","pairingMessage","browserSupported","darkMode","key","defaultValue","res","localStorage","getItem","JSON","parse","e","loadPreference","aboutDialogVisible","setState","setLoading","setPairingFailed","setPairingMessage","setBrowserSupported","setDarkMode","value","setItem","stringify","showAboutDialog","disc","deviceName","setDisc","setDeviceName","store","configureStore","renameDialog","uploadDialog","errorDialog","convertDialog","appState","main","middleware","getDefaultMiddleware","dispatch","a","appStateActions","serviceRegistry","netmdService","batchActions","mainActions","WireformatDict","SP","Wireformat","pcm","LP2","lp2","LP105","l105kbps","LP4","lp4","Module","Transition","React","forwardRef","props","ref","Slide","direction","AboutDialog","useDispatch","Dialog","open","maxWidth","fullWidth","TransitionComponent","aria-labelledby","DialogTitle","id","DialogContent","DialogContentText","Link","rel","href","target","DialogActions","Button","onClick","appActions","TopMenu","useState","menuAnchorEl","setMenuAnchorEl","menuOpen","handleMenuClose","menuItems","push","MenuItem","wipeDisc","Fragment","IconButton","aria-label","aria-controls","aria-haspopup","event","currentTarget","Menu","anchorEl","keepMounted","onClose","useStyles","makeStyles","theme","position","flex","display","justifyContent","flexDirection","alignItems","button","marginTop","spacing","minWidth","chromeLogo","width","height","why","alignSelf","headBox","Welcome","classes","toLowerCase","showWhyUnsupported","setWhyUnsupported","Box","className","Typography","component","variant","align","color","getState","audioExportService","init","connect","pair","message","FormControl","style","visibility","FormHelperText","preventDefault","alt","src","ChromeIconPath","RenameDialog","renameDialogVisible","renameDialogTitle","renameDialogIndex","handleCancelRename","renameDialogActions","handleDoRename","newName","renameTrack","TextField","autoFocus","label","type","onKeyDown","onChange","progressPerc","progressBar","uploadLabel","UploadDialog","progressValue","Math","floor","bufferValue","convertedValue","aria-describedby","LinearProgress","valueBuffer","ErrorDialog","errorDialogActions","container","formControl","ConvertDialog","handleClose","convertDialogActions","InputLabel","Select","labelId","ev","input","Input","files","wireformat","uploadDialogActions","updateProgressCallback","trackUpdate","length","updateTrack","conversionIterator","convertNext","i","f","converted","Promise","resolve","reject","prepare","export","file","errorMessage","j","item","upload","actionToDispatch","concat","errorDialogAction","convertAndUpload","add","bottom","right","overflowY","marginBottom","marginLeft","marginRight","outline","toolbar","breakpoints","up","toolbarLabel","toolbarHighlight","palette","secondary","backgroundColor","lighten","light","text","primary","dark","formatBadge","BadgeImpl","badge","colorPrimary","border","background","paper","padding","titleCell","overflow","textOverflow","backdrop","zIndex","drawer","EncodingName","Encoding","sp","Main","selected","setSelected","selectedCount","useEffect","uploadedFiles","setUploadedFiles","onDrop","useCallback","acceptedFiles","rejectedFiles","useDropzone","accept","noClick","getRootProps","getInputProps","isDragActive","tracks","groups","group","track","encoding","duration","formatTimeFromFrames","handleRenameDoubleClick","selectedIndex","currentName","getTracks","find","left","Toolbar","clsx","Checkbox","indeterminate","checked","map","t","inputProps","Tooltip","indexes","sort","reverse","deleteTrack","disabled","Table","size","TableHead","TableRow","TableCell","TableBody","hover","includes","onDoubleClick","filter","Backdrop","Fab","layout","copyright","minidiscLogo","darkTheme","createMuiTheme","contrastText","lightTheme","App","ThemeProvider","CssBaseline","Paper","undefined","Date","getFullYear","data-via","data-hashtags","data-dnt","data-show-count","CircularProgress","AtracdencProcess","worker","messageCallback","onmessage","handleMessage","bind","postMessage","bitrate","eventData","result","WorkerGlobalScope","self","others","importScripts","m","setLogger","msg","stream","dataArray","Uint8Array","FS","writeFile","callMain","fileStat","stat","tmp","outAt3FileStream","read","close","buffer","AtracdencWorker","FFMpegAudioExportService","ffmpegProcess","atracdencProcess","loglines","inFileName","outFileNameNoExt","setLogging","createWorker","logger","corePath","workerPath","load","ext","split","Error","write","transcode","audioFormatRegex","inputFormatRegex","line","outFileName","encode","addEventListener","returnValue","ondisconnect","ReactDOM","render","document","getElementById","URL","origin","fetch","headers","response","contentType","get","status","indexOf","ready","unregister","reload","checkValidServiceWorker"],"mappings":"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","file":"static/js/main.a222d332.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/chrome-icon.f3b6c54c.svg\";","module.exports = function() {\n return new Worker(__webpack_public_path__ + \"cc43d050d6e858b79f86.worker.js\");\n};","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(/^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/final-service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' + 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n console.log('state change', installingWorker.state);\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n registration.update(); // Check for new version everytime we load the page\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' },\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log('No internet connection found. App is running in offline mode.');\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import { openNewDevice, NetMDInterface, Disc, listContent, openPairedDevice, Wireformat, MDTrack, download } from 'netmd-js';\nimport { makeGetAsyncPacketIteratorOnWorkerThread } from 'netmd-js/dist/web-encrypt-worker';\n\nconst Worker = require('worker-loader!netmd-js/dist/web-encrypt-worker.js'); // eslint-disable-line import/no-webpack-loader-syntax\n\nexport interface NetMDService {\n pair(): Promise;\n connect(): Promise;\n listContent(): Promise;\n getDeviceName(): Promise;\n finalize(): Promise;\n renameTrack(index: number, newTitle: string): Promise;\n deleteTrack(index: number): Promise;\n wipeDisc(): Promise;\n upload(\n title: string,\n data: ArrayBuffer,\n format: Wireformat,\n progressCallback: (progress: { written: number; encrypted: number; total: number }) => void\n ): Promise;\n}\n\nexport class NetMDUSBService implements NetMDService {\n private netmdInterface?: NetMDInterface;\n\n async pair() {\n let iface = await openNewDevice(navigator.usb);\n if (iface === null) {\n return false;\n }\n this.netmdInterface = iface;\n return true;\n }\n\n async connect() {\n let iface = await openPairedDevice(navigator.usb);\n if (iface === null) {\n return false;\n }\n this.netmdInterface = iface;\n return true;\n }\n\n async listContent() {\n return await listContent(this.netmdInterface!);\n }\n\n async getDeviceName() {\n return await this.netmdInterface!.netMd.getDeviceName();\n }\n\n async finalize() {\n await this.netmdInterface!.netMd.finalize();\n }\n\n async renameTrack(index: number, newTitle: string) {\n await this.netmdInterface!.setTrackTitle(index, newTitle);\n }\n\n async deleteTrack(index: number) {\n await this.netmdInterface!.eraseTrack(index);\n }\n\n async wipeDisc() {\n await this.netmdInterface!.eraseDisc();\n }\n\n async upload(\n title: string,\n data: ArrayBuffer,\n format: Wireformat,\n progressCallback: (progress: { written: number; encrypted: number; total: number }) => void\n ) {\n let total = data.byteLength;\n let written = 0;\n let encrypted = 0;\n function updateProgress() {\n progressCallback({ written, encrypted, total });\n }\n\n let w = new Worker();\n\n let webWorkerAsyncPacketIterator = makeGetAsyncPacketIteratorOnWorkerThread(w, ({ encryptedBytes }) => {\n encrypted = encryptedBytes;\n updateProgress();\n });\n\n let mdTrack = new MDTrack(title, format, data, 0x80000, webWorkerAsyncPacketIterator);\n\n await download(this.netmdInterface!, mdTrack, ({ writtenBytes }) => {\n written = writtenBytes;\n updateProgress();\n });\n }\n}\n","import { NetMDService } from './netmd';\nimport { AudioExportService } from './audio-export';\n\ninterface ServiceRegistry {\n netmdService?: NetMDService;\n audioExportService?: AudioExportService;\n}\n\nconst ServiceRegistry: ServiceRegistry = {};\n\nexport default ServiceRegistry;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface LoadingDialogState {\n visible: boolean;\n writtenProgress: number;\n encryptedProgress: number;\n totalProgress: number;\n\n trackTotal: number;\n trackConverting: number;\n trackCurrent: number;\n\n titleCurrent: string;\n titleConverting: string;\n}\n\nconst initialState: LoadingDialogState = {\n visible: false,\n // Current Track Upload\n writtenProgress: 0,\n encryptedProgress: 0,\n totalProgress: 1,\n\n // Tracks done\n trackTotal: 1,\n trackConverting: 0,\n trackCurrent: 0,\n titleCurrent: '',\n titleConverting: '',\n};\n\nexport const slice = createSlice({\n name: 'uploadDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setWriteProgress: (state, action: PayloadAction<{ written: number; encrypted: number; total: number }>) => {\n state.encryptedProgress = action.payload.encrypted;\n state.writtenProgress = action.payload.written;\n state.totalProgress = action.payload.total;\n },\n setTrackProgress: (\n state,\n action: PayloadAction<{ total: number; current: number; converting: number; titleCurrent: string; titleConverting: string }>\n ) => {\n state.trackTotal = action.payload.total;\n state.trackCurrent = action.payload.current;\n state.trackConverting = action.payload.converting;\n state.titleCurrent = action.payload.titleCurrent;\n state.titleConverting = action.payload.titleConverting;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface RenameDialogState {\n visible: boolean;\n title: string;\n index: number;\n}\n\nconst initialState: RenameDialogState = {\n visible: false,\n title: '',\n index: -1,\n};\n\nexport const slice = createSlice({\n name: 'renameDialog',\n initialState,\n reducers: {\n setVisible: (state: RenameDialogState, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setCurrentName: (state: RenameDialogState, action: PayloadAction) => {\n state.title = action.payload;\n },\n setIndex: (state: RenameDialogState, action: PayloadAction) => {\n state.index = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface ErrorDialogState {\n visible: boolean;\n error: string;\n}\n\nconst initialState: ErrorDialogState = {\n visible: false,\n error: ``,\n};\n\nconst slice = createSlice({\n name: 'errorDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setErrorMessage: (state, action: PayloadAction) => {\n state.error = `${action.payload}`;\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface ConvertDialogFeature {\n visible: boolean;\n format: string;\n}\n\nconst initialState: ConvertDialogFeature = {\n visible: false,\n format: `LP2`,\n};\n\nconst slice = createSlice({\n name: 'convertDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setFormat: (state, action: PayloadAction) => {\n state.format = action.payload;\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { useSelector, shallowEqual } from 'react-redux';\nimport { RootState } from './redux/store';\n\nexport function sleep(ms: number) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\nexport function useShallowEqualSelector(selector: (state: TState) => TSelected): TSelected {\n return useSelector(selector, shallowEqual);\n}\n\nexport function hasWebUSB(): boolean {\n return !!navigator.usb;\n}\n\nexport function getWebUSB(): USB {\n return navigator.usb;\n}\n\nexport function debugEnabled() {\n return process.env.NODE_ENV === 'development';\n}\n\nexport function getPublicPathFor(script: string) {\n return `${process.env.PUBLIC_URL}/${script}`;\n}\n\nexport function savePreference(key: string, value: unknown) {\n localStorage.setItem(key, JSON.stringify(value));\n}\n\nexport function loadPreference(key: string, defaultValue: T): T {\n let res = localStorage.getItem(key);\n if (res === null) {\n return defaultValue;\n } else {\n try {\n return JSON.parse(res) as T;\n } catch (e) {\n return defaultValue;\n }\n }\n}\n\ndeclare let process: any;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\nimport { savePreference, loadPreference } from '../utils';\n\ntype Views = 'WELCOME' | 'MAIN';\n\nexport interface AppState {\n mainView: Views;\n loading: boolean;\n pairingFailed: boolean;\n pairingMessage: string;\n browserSupported: boolean;\n darkMode: boolean;\n aboutDialogVisible: boolean;\n}\n\nconst initialState: AppState = {\n mainView: 'WELCOME',\n loading: false,\n pairingFailed: false,\n pairingMessage: ``,\n browserSupported: true,\n darkMode: loadPreference('darkMode', false),\n aboutDialogVisible: false,\n};\n\nexport const slice = createSlice({\n name: 'app',\n initialState,\n reducers: {\n setState: (state, action: PayloadAction) => {\n state.mainView = action.payload;\n },\n setLoading: (state, action: PayloadAction) => {\n state.loading = action.payload;\n },\n setPairingFailed: (state, action: PayloadAction) => {\n state.pairingFailed = action.payload;\n },\n setPairingMessage: (state, action: PayloadAction) => {\n state.pairingMessage = action.payload;\n },\n setBrowserSupported: (state, action: PayloadAction) => {\n state.browserSupported = action.payload;\n },\n setDarkMode: (state, action: PayloadAction) => {\n state.darkMode = action.payload;\n savePreference('darkMode', state.darkMode);\n },\n showAboutDialog: (state, action: PayloadAction) => {\n state.aboutDialogVisible = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { Disc } from 'netmd-js';\nimport { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface MainState {\n disc: Disc | null;\n deviceName: string;\n}\n\nconst initialState: MainState = {\n disc: null,\n deviceName: '',\n};\n\nexport const slice = createSlice({\n name: 'main',\n initialState,\n reducers: {\n setDisc: (state, action: PayloadAction) => {\n state.disc = action.payload;\n },\n setDeviceName: (state, action: PayloadAction) => {\n state.deviceName = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';\nimport uploadDialog from './upload-dialog-feature';\nimport renameDialog from './rename-dialog-feature';\nimport errorDialog from './error-dialog-feature';\nimport convertDialog from './convert-dialog-feature';\nimport appState from './app-feature';\nimport main from './main-feature';\n\nexport const store = configureStore({\n reducer: {\n renameDialog,\n uploadDialog,\n errorDialog,\n convertDialog,\n appState,\n main,\n },\n middleware: [...getDefaultMiddleware()],\n});\n\nexport type RootState = ReturnType;\nexport type AppDispatch = typeof store.dispatch;\n","import { batchActions } from 'redux-batched-actions';\nimport { AppDispatch, RootState } from './store';\nimport { actions as uploadDialogActions } from './upload-dialog-feature';\nimport { actions as renameDialogActions } from './rename-dialog-feature';\nimport { actions as errorDialogAction } from './error-dialog-feature';\nimport { actions as appStateActions } from './app-feature';\nimport { actions as mainActions } from './main-feature';\nimport serviceRegistry from '../services/registry';\nimport { Wireformat } from 'netmd-js';\nimport { AnyAction } from '@reduxjs/toolkit';\n\nexport function pair() {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n dispatch(appStateActions.setPairingFailed(false));\n\n await serviceRegistry.audioExportService!.init();\n\n try {\n let connected = await serviceRegistry.netmdService!.connect();\n if (connected) {\n dispatch(appStateActions.setState('MAIN'));\n return;\n }\n } catch (err) {\n console.error(err);\n // In case of error, just log and try to pair\n }\n\n try {\n let paired = await serviceRegistry.netmdService!.pair();\n if (paired) {\n dispatch(appStateActions.setState('MAIN'));\n return;\n }\n dispatch(batchActions([appStateActions.setPairingMessage(`Connection Failed`), appStateActions.setPairingFailed(true)]));\n } catch (err) {\n console.error(err);\n let message = (err as Error).message;\n dispatch(batchActions([appStateActions.setPairingMessage(message), appStateActions.setPairingFailed(true)]));\n }\n };\n}\n\nexport function listContent() {\n return async function(dispatch: AppDispatch) {\n // Issue loading\n dispatch(appStateActions.setLoading(true));\n let disc = await serviceRegistry.netmdService!.listContent();\n let deviceName = await serviceRegistry.netmdService!.getDeviceName();\n dispatch(batchActions([mainActions.setDisc(disc), mainActions.setDeviceName(deviceName), appStateActions.setLoading(false)]));\n };\n}\n\nexport function renameTrack({ index, newName }: { index: number; newName: string }) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n await netmdService!.renameTrack(index, newName);\n dispatch(renameDialogActions.setVisible(false));\n listContent()(dispatch);\n };\n}\n\nexport function deleteTracks(indexes: number[]) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n dispatch(appStateActions.setLoading(true));\n indexes = indexes.sort();\n indexes.reverse();\n for (let index of indexes) {\n await netmdService!.deleteTrack(index);\n }\n listContent()(dispatch);\n };\n}\n\nexport function wipeDisc() {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n dispatch(appStateActions.setLoading(true));\n await netmdService!.wipeDisc();\n listContent()(dispatch);\n };\n}\n\nexport const WireformatDict: { [k: string]: Wireformat } = {\n SP: Wireformat.pcm,\n LP2: Wireformat.lp2,\n LP105: Wireformat.l105kbps,\n LP4: Wireformat.lp4,\n};\n\nexport function convertAndUpload(files: File[], format: string) {\n return async function(dispatch: AppDispatch, getState: (state: RootState) => void) {\n const { audioExportService, netmdService } = serviceRegistry;\n const wireformat = WireformatDict[format];\n\n dispatch(uploadDialogActions.setVisible(true));\n\n const updateProgressCallback = ({ written, encrypted, total }: { written: number; encrypted: number; total: number }) => {\n dispatch(uploadDialogActions.setWriteProgress({ written, encrypted, total }));\n };\n\n let trackUpdate: {\n current: number;\n converting: number;\n total: number;\n titleCurrent: string;\n titleConverting: string;\n } = {\n current: 0,\n converting: 0,\n total: files.length,\n titleCurrent: '',\n titleConverting: '',\n };\n const updateTrack = () => {\n dispatch(uploadDialogActions.setTrackProgress(trackUpdate));\n };\n\n let conversionIterator = async function*(files: File[]) {\n let converted: Promise<{ file: File; data: ArrayBuffer }>[] = [];\n\n let i = 0;\n function convertNext() {\n if (i === files.length) {\n trackUpdate.converting = i;\n trackUpdate.titleConverting = ``;\n updateTrack();\n return;\n }\n\n let f = files[i];\n trackUpdate.converting = i;\n trackUpdate.titleConverting = f.name;\n updateTrack();\n i++;\n\n converted.push(\n new Promise(async (resolve, reject) => {\n let data: ArrayBuffer;\n try {\n await audioExportService!.prepare(f);\n data = await audioExportService!.export({ format });\n convertNext();\n resolve({ file: f, data: data });\n } catch (err) {\n error = err;\n errorMessage = `${f.name}: Unsupported or unrecognized format`;\n reject(err);\n }\n })\n );\n }\n convertNext();\n\n let j = 0;\n while (j < converted.length) {\n yield await converted[j];\n j++;\n }\n };\n\n let error: any;\n let errorMessage = ``;\n let i = 1;\n for await (let item of conversionIterator(files)) {\n const { file, data } = item;\n\n trackUpdate.current = i++;\n trackUpdate.titleCurrent = file.name;\n updateTrack();\n updateProgressCallback({ written: 0, encrypted: 0, total: 100 });\n try {\n await netmdService?.upload(file.name, data, wireformat, updateProgressCallback);\n } catch (err) {\n error = err;\n errorMessage = `${file.name}: Error uploading to device`;\n break;\n }\n }\n\n let actionToDispatch: AnyAction[] = [uploadDialogActions.setVisible(false)];\n\n if (error) {\n console.error(error);\n actionToDispatch = actionToDispatch.concat([\n errorDialogAction.setVisible(true),\n errorDialogAction.setErrorMessage(errorMessage),\n ]);\n }\n\n dispatch(batchActions(actionToDispatch));\n listContent()(dispatch);\n };\n}\n","/* eslint no-restricted-globals: 0 */\nimport { getPublicPathFor } from '../utils';\nexport class AtracdencProcess {\n private messageCallback?: (ev: MessageEvent) => void;\n\n constructor(public worker: Worker) {\n worker.onmessage = this.handleMessage.bind(this);\n }\n\n async init() {\n await new Promise(resolve => {\n this.messageCallback = resolve;\n this.worker.postMessage({ action: 'init' });\n });\n }\n\n async encode(data: ArrayBuffer, bitrate: string) {\n let eventData = await new Promise(resolve => {\n this.messageCallback = resolve;\n this.worker.postMessage({ action: 'encode', bitrate, data }, [data]);\n });\n return eventData.data.result as Uint8Array;\n }\n\n handleMessage(ev: MessageEvent) {\n this.messageCallback!(ev);\n this.messageCallback = undefined;\n }\n}\n\nif (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {\n // Worker\n let Module: any;\n onmessage = async (ev: MessageEvent) => {\n const { action, ...others } = ev.data;\n if (action === 'init') {\n self.importScripts(getPublicPathFor(`atracdenc.js`));\n (self as any).Module().then((m: any) => {\n Module = m;\n self.postMessage({ action: 'init' });\n Module.setLogger && Module.setLogger((msg: string, stream: string) => console.log(`${stream}: ${msg}`));\n });\n } else if (action === 'encode') {\n const { bitrate, data } = others;\n const inWavFile = `inWavFile.wav`;\n const outAt3File = `outAt3File.aea`;\n const dataArray = new Uint8Array(data);\n Module.FS.writeFile(`${inWavFile}`, dataArray);\n Module.callMain([`-e`, `atrac3`, `-i`, inWavFile, `-o`, outAt3File, `--bitrate`, bitrate]);\n\n // Read file and trim header (96 bytes)\n let fileStat = Module.FS.stat(outAt3File);\n let size = fileStat.size;\n let tmp = new Uint8Array(size - 96);\n let outAt3FileStream = Module.FS.open(outAt3File, 'r');\n Module.FS.read(outAt3FileStream, tmp, 0, tmp.length, 96);\n Module.FS.close(outAt3FileStream);\n\n let result = tmp.buffer;\n\n self.postMessage(\n {\n action: 'encode',\n result,\n },\n [result]\n );\n self.close();\n }\n };\n} else {\n // Main\n}\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as appActions } from '../redux/app-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport Link from '@material-ui/core/Link';\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nexport const AboutDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let visible = useShallowEqualSelector(state => state.appState.aboutDialogVisible);\n\n const handleClose = () => {\n dispatch(appActions.showAboutDialog(false));\n };\n\n return (\n \n About Web MiniDisc\n \n Web MiniDisc has been made possible by\n
    \n
  • \n \n FFmpeg\n {' '}\n and{' '}\n \n ffmpegjs\n \n , to read your audio files (wav, mp3, ogg, mp4, etc...).\n
  • \n
  • \n \n Atracdenc\n \n , to support atrac3 encoding (lp2, lp4 audio formats).\n
  • \n
  • \n \n Emscripten\n \n , to run both FFmpeg and Atracdenc in the browser.\n
  • \n
  • \n \n netmd-js\n \n , to send commands to NetMD devices using Javascript.\n
  • \n
  • \n \n linux-minidisc\n \n , to make the netmd-js project possible.\n
  • \n
  • \n \n material-ui\n \n , to build the user interface.\n
  • \n
\n Attribution\n
    \n
  • \n MiniDisc logo from{' '}\n \n https://en.wikipedia.org/wiki/MiniDisc\n \n
  • \n
  • \n MiniDisc icon from{' '}\n \n http://fav.me/d7u3g3g\n \n
  • \n
\n
\n \n \n \n \n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MoreVertIcon from '@material-ui/icons/MoreVert';\n\nimport { wipeDisc, listContent } from '../redux/actions';\nimport { actions as appActions } from '../redux/app-feature';\nimport { useShallowEqualSelector } from '../utils';\nimport Link from '@material-ui/core/Link';\n\nexport const TopMenu = function() {\n const dispatch = useDispatch();\n\n let { mainView } = useShallowEqualSelector(state => state.appState);\n\n const [menuAnchorEl, setMenuAnchorEl] = React.useState(null);\n const menuOpen = Boolean(menuAnchorEl);\n const handleMenuClick = (event: React.MouseEvent) => {\n setMenuAnchorEl(event.currentTarget);\n };\n\n const handleMenuClose = () => {\n setMenuAnchorEl(null);\n };\n\n const handleWipeDisc = () => {\n dispatch(wipeDisc());\n handleMenuClose();\n };\n\n const handleRefresh = () => {\n dispatch(listContent());\n handleMenuClose();\n };\n\n const handleExit = () => {\n dispatch(appActions.setState('WELCOME'));\n handleMenuClose();\n };\n const handleShowAbout = () => {\n dispatch(appActions.showAboutDialog(true));\n handleMenuClose();\n };\n\n const menuItems = [];\n if (mainView === 'MAIN') {\n menuItems.push(\n \n Refresh\n \n );\n menuItems.push(\n \n Wipe Disc\n \n );\n menuItems.push(\n \n Exit\n \n );\n }\n menuItems.push(\n \n About\n \n );\n menuItems.push(\n \n \n Fork me on GitHub\n \n \n );\n\n return (\n \n \n \n \n \n {menuItems}\n \n \n );\n};\n","import React, { useState } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { pair } from '../redux/actions';\n\nimport { useShallowEqualSelector } from '../utils';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Button from '@material-ui/core/Button';\nimport Typography from '@material-ui/core/Typography';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport Box from '@material-ui/core/Box';\nimport Link from '@material-ui/core/Link';\n\nimport { AboutDialog } from './about-dialog';\nimport { TopMenu } from './topmenu';\nimport ChromeIconPath from '../images/chrome-icon.svg';\n\nconst useStyles = makeStyles(theme => ({\n main: {\n position: 'relative',\n flex: '1 1 auto',\n display: 'flex',\n justifyContent: 'center',\n flexDirection: 'column',\n alignItems: 'center',\n },\n button: {\n marginTop: theme.spacing(3),\n minWidth: 150,\n },\n spacing: {\n marginTop: theme.spacing(1),\n },\n chromeLogo: {\n marginTop: theme.spacing(1),\n width: 96,\n height: 96,\n },\n why: {\n alignSelf: 'flex-start',\n marginTop: theme.spacing(3),\n },\n headBox: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n}));\n\nexport const Welcome = (props: {}) => {\n const classes = useStyles();\n\n const dispatch = useDispatch();\n const { browserSupported, pairingFailed, pairingMessage } = useShallowEqualSelector(state => state.appState);\n if (pairingMessage.toLowerCase().match(/denied/)) {\n // show linux instructions\n }\n // Access denied.\n\n const [showWhyUnsupported, setWhyUnsupported] = useState(false);\n const handleLearnWhy = (event: React.SyntheticEvent) => {\n event.preventDefault();\n setWhyUnsupported(true);\n };\n\n return (\n \n \n \n Web MiniDisc\n \n \n \n \n Brings NetMD Devices to the Web\n \n \n {browserSupported ? (\n \n \n Press the button to connect to a NetMD device\n \n\n \n\n \n {pairingMessage}\n \n \n ) : (\n \n \n This Web browser is not supported. \n \n Learn Why\n \n \n\n \n \"Chrome\n \n\n \n Try using{' '}\n \n Chrome\n {' '}\n instead\n \n\n {showWhyUnsupported ? (\n <>\n \n Web MiniDisc requires a browser that supports both{' '}\n \n WebUSB\n {' '}\n and{' '}\n \n WebAssembly\n \n .\n \n
    \n
  • WebUSB is needed to control the NetMD device via the USB connection to your computer.
  • \n
  • WebAssembly is used to convert the music to a MiniDisc compatible format
  • \n
\n \n ) : null}\n
\n )}\n
\n \n
\n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { renameTrack } from '../redux/actions';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport TextField from '@material-ui/core/TextField';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nexport const RenameDialog = (props: {}) => {\n let dispatch = useDispatch();\n\n let renameDialogVisible = useShallowEqualSelector(state => state.renameDialog.visible);\n let renameDialogTitle = useShallowEqualSelector(state => state.renameDialog.title);\n let renameDialogIndex = useShallowEqualSelector(state => state.renameDialog.index);\n\n const handleCancelRename = () => {\n dispatch(renameDialogActions.setVisible(false));\n };\n\n const handleDoRename = () => {\n dispatch(renameTrack({ index: renameDialogIndex, newName: renameDialogTitle }));\n };\n\n return (\n \n Rename Track\n \n {\n event.key === `Enter` && handleDoRename();\n }}\n onChange={event => {\n dispatch(renameDialogActions.setCurrentName(event.target.value));\n }}\n />\n \n \n \n \n \n \n );\n};\n","import React from 'react';\nimport { useShallowEqualSelector } from '../utils';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\n\nconst useStyles = makeStyles(theme => ({\n progressPerc: {\n marginTop: theme.spacing(1),\n },\n progressBar: {\n marginTop: theme.spacing(3),\n },\n uploadLabel: {\n marginTop: theme.spacing(3),\n },\n}));\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nexport const UploadDialog = (props: {}) => {\n const classes = useStyles();\n\n let {\n visible,\n writtenProgress,\n encryptedProgress,\n totalProgress,\n\n trackTotal,\n trackCurrent,\n trackConverting,\n titleCurrent,\n titleConverting,\n } = useShallowEqualSelector(state => state.uploadDialog);\n\n let progressValue = Math.floor((writtenProgress / totalProgress) * 100);\n let bufferValue = Math.floor((encryptedProgress / totalProgress) * 100);\n let convertedValue = Math.floor((trackConverting / trackTotal) * 100);\n return (\n \n Recording...\n \n \n {convertedValue === 100 && trackConverting === trackTotal\n ? `Conversion completed`\n : `Converting ${trackConverting + 1} of ${trackTotal}: ${titleConverting}`}\n \n \n {convertedValue}%\n\n \n Uploading {trackCurrent} of {trackTotal}: {titleCurrent}\n \n \n {progressValue}%\n \n \n \n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as errorDialogActions } from '../redux/error-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nexport const ErrorDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let { visible, error } = useShallowEqualSelector(state => state.errorDialog);\n\n const handleClose = () => {\n dispatch(errorDialogActions.setVisible(false));\n };\n\n return (\n \n Error\n \n {error}\n \n \n \n \n \n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as convertDialogActions } from '../redux/convert-dialog-feature';\nimport { convertAndUpload } from '../redux/actions';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport FormControl from '@material-ui/core/FormControl';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport Select from '@material-ui/core/Select';\nimport Input from '@material-ui/core/Input';\nimport MenuItem from '@material-ui/core/MenuItem';\n\nconst Transition = React.forwardRef(function Transition(props, ref) {\n return ;\n});\n\nconst useStyles = makeStyles(theme => ({\n container: {\n display: 'flex',\n flexDirection: 'row',\n },\n formControl: {\n minWidth: 120,\n },\n}));\n\nexport const ConvertDialog = (props: { files: File[] }) => {\n const dispatch = useDispatch();\n const classes = useStyles();\n\n let { visible, format } = useShallowEqualSelector(state => state.convertDialog);\n\n const handleClose = () => {\n dispatch(convertDialogActions.setVisible(false));\n };\n\n const handleChange = (ev: React.ChangeEvent<{ value: unknown }>) => {\n dispatch(convertDialogActions.setFormat(ev.target.value as string));\n };\n\n const handleConvert = () => {\n handleClose();\n dispatch(convertAndUpload(props.files, format));\n };\n\n return (\n \n Upload Settings\n \n \n \n Format\n \n }\n >\n SP\n LP2\n LP4\n \n \n \n \n \n \n \n \n );\n};\n","import React, { useEffect, useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport clsx from 'clsx';\nimport { useDropzone } from 'react-dropzone';\nimport { listContent, deleteTracks } from '../redux/actions';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { actions as convertDialogActions } from '../redux/convert-dialog-feature';\n\nimport { formatTimeFromFrames, getTracks, Encoding } from 'netmd-js';\n\nimport { useShallowEqualSelector } from '../utils';\n\nimport { lighten, makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport Box from '@material-ui/core/Box';\nimport Fab from '@material-ui/core/Fab';\nimport AddIcon from '@material-ui/icons/Add';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport EditIcon from '@material-ui/icons/Edit';\nimport Backdrop from '@material-ui/core/Backdrop';\n\nimport Table from '@material-ui/core/Table';\nimport TableBody from '@material-ui/core/TableBody';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableHead from '@material-ui/core/TableHead';\nimport TableRow from '@material-ui/core/TableRow';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { batchActions } from 'redux-batched-actions';\n\nimport { RenameDialog } from './rename-dialog';\nimport { UploadDialog } from './upload-dialog';\nimport { ErrorDialog } from './error-dialog';\nimport { ConvertDialog } from './convert-dialog';\nimport { AboutDialog } from './about-dialog';\nimport { TopMenu } from './topmenu';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport * as BadgeImpl from '@material-ui/core/Badge/Badge';\n\nconst useStyles = makeStyles(theme => ({\n add: {\n position: 'absolute',\n bottom: theme.spacing(3),\n right: theme.spacing(3),\n },\n main: {\n overflowY: 'auto',\n flex: '1 1 auto',\n marginBottom: theme.spacing(3),\n marginLeft: theme.spacing(-2),\n marginRight: theme.spacing(-2),\n outline: 'none',\n },\n toolbar: {\n marginTop: theme.spacing(3),\n marginLeft: theme.spacing(-2),\n marginRight: theme.spacing(-2),\n [theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {\n marginLeft: theme.spacing(-3),\n marginRight: theme.spacing(-3),\n },\n },\n toolbarLabel: {\n flex: '1 1 100%',\n },\n toolbarHighlight:\n theme.palette.type === 'light'\n ? {\n color: theme.palette.secondary.main,\n backgroundColor: lighten(theme.palette.secondary.light, 0.85),\n }\n : {\n color: theme.palette.text.primary,\n backgroundColor: theme.palette.secondary.dark,\n },\n headBox: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n spacing: {\n marginTop: theme.spacing(1),\n },\n formatBadge: {\n ...(BadgeImpl as any).styles(theme).badge,\n ...(BadgeImpl as any).styles(theme).colorPrimary,\n position: 'static',\n display: 'inline-flex',\n border: `2px solid ${theme.palette.background.paper}`,\n padding: '0 4px',\n },\n titleCell: {\n overflow: 'hidden',\n maxWidth: '40ch',\n textOverflow: 'ellipsis',\n // whiteSpace: 'nowrap',\n },\n backdrop: {\n zIndex: theme.zIndex.drawer + 1,\n color: '#fff',\n },\n}));\n\nconst EncodingName: { [k: number]: string } = {\n [Encoding.sp]: 'SP',\n [Encoding.lp2]: 'LP2',\n [Encoding.lp4]: 'LP4',\n};\n\nexport const Main = (props: {}) => {\n let dispatch = useDispatch();\n let disc = useShallowEqualSelector(state => state.main.disc);\n let deviceName = useShallowEqualSelector(state => state.main.deviceName);\n\n const [selected, setSelected] = React.useState([]);\n const selectedCount = selected.length;\n\n useEffect(() => {\n dispatch(listContent());\n }, [dispatch]);\n\n useEffect(() => {\n setSelected([]); // Reset selection if disc changes\n }, [disc]);\n\n let [uploadedFiles, setUploadedFiles] = React.useState([]);\n const onDrop = useCallback(\n (acceptedFiles: File[], rejectedFiles: File[]) => {\n setUploadedFiles(acceptedFiles);\n dispatch(convertDialogActions.setVisible(true));\n },\n [dispatch]\n );\n const { getRootProps, getInputProps, isDragActive, open } = useDropzone({ onDrop, accept: `audio/*`, noClick: true });\n\n const classes = useStyles();\n\n let tracks: { index: number; title: string; group: string; duration: string; encoding: string }[] = [];\n if (disc !== null) {\n for (let group of disc.groups) {\n for (let track of group.tracks) {\n tracks.push({\n index: track.index,\n title: track.title ?? `Unknown Title`,\n group: group.title ?? ``,\n encoding: EncodingName[track.encoding],\n duration: formatTimeFromFrames(track.duration, false),\n });\n }\n }\n }\n\n // Action Handlers\n const handleSelectClick = (event: React.MouseEvent, item: number) => {\n if (selected.includes(item)) {\n setSelected(selected.filter(i => i !== item));\n } else {\n setSelected([...selected, item]);\n }\n };\n\n const handleSelectAllClick = (event: React.ChangeEvent) => {\n if (selected.length < tracks.length) {\n setSelected(tracks.map(t => t.index));\n } else {\n setSelected([]);\n }\n };\n\n const handleRenameDoubleClick = (event: React.MouseEvent, item: number) => {\n let selectedIndex = item;\n let currentName = getTracks(disc!).find(track => track.index === selectedIndex)?.title ?? '';\n\n dispatch(\n batchActions([\n renameDialogActions.setVisible(true),\n renameDialogActions.setCurrentName(currentName),\n renameDialogActions.setIndex(selectedIndex),\n ])\n );\n };\n\n const handleRenameActionClick = (event: React.MouseEvent) => {\n handleRenameDoubleClick(event, selected[0]);\n };\n\n const handleDeleteSelected = (event: React.MouseEvent) => {\n dispatch(deleteTracks(selected));\n };\n\n return (\n \n \n \n {deviceName || `Loading...`}\n \n \n \n \n {disc !== null\n ? `${formatTimeFromFrames(disc.left, false)} left of ${formatTimeFromFrames(disc.total, false)}`\n : `Loading...`}\n \n 0,\n })}\n >\n {selectedCount > 0 ? (\n 0 && selectedCount < tracks.length}\n checked={selectedCount > 0}\n onChange={handleSelectAllClick}\n inputProps={{ 'aria-label': 'select all tracks' }}\n />\n ) : null}\n {selectedCount > 0 ? (\n \n {selectedCount} selected\n \n ) : (\n \n Content\n \n )}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n \n \n \n \n \n \n Title\n Format\n Duration\n \n \n \n {tracks.map(track => (\n handleRenameDoubleClick(event, track.index)}\n onClick={event => handleSelectClick(event, track.index)}\n >\n \n {track.title || `No Title`}\n \n \n {track.encoding}\n \n {track.duration}\n \n ))}\n \n
\n \n Drop your Music to Upload\n \n
\n \n \n \n\n \n \n \n \n \n
\n );\n};\n","import React from 'react';\nimport { useShallowEqualSelector } from '../utils';\nimport { actions as appActions } from '../redux/app-feature';\n\nimport CssBaseline from '@material-ui/core/CssBaseline';\nimport Backdrop from '@material-ui/core/Backdrop';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport { makeStyles, createMuiTheme, ThemeProvider } from '@material-ui/core/styles';\n\nimport { Welcome } from './welcome';\nimport { Main } from './main';\nimport Paper from '@material-ui/core/Paper';\nimport Typography from '@material-ui/core/Typography';\nimport Link from '@material-ui/core/Link';\nimport Box from '@material-ui/core/Box';\nimport Brightness2Icon from '@material-ui/icons/Brightness2';\nimport IconButton from '@material-ui/core/IconButton';\nimport { useDispatch } from 'react-redux';\n\nconst useStyles = makeStyles(theme => ({\n layout: {\n width: 'auto',\n height: '100%',\n [theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {\n width: 600,\n marginLeft: 'auto',\n marginRight: 'auto',\n },\n },\n\n paper: {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n padding: theme.spacing(2),\n height: '100%',\n [theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {\n marginTop: theme.spacing(6),\n marginBottom: theme.spacing(6),\n padding: theme.spacing(3),\n height: 600,\n },\n },\n copyright: {\n display: 'flex',\n alignItems: 'center',\n },\n backdrop: {\n zIndex: theme.zIndex.drawer + 1,\n color: '#fff',\n },\n minidiscLogo: {\n width: 48,\n },\n}));\n\nconst darkTheme = createMuiTheme({\n palette: {\n type: 'dark',\n primary: {\n light: '#6ec6ff',\n main: '#2196f3',\n dark: '#0069c0',\n contrastText: '#fff',\n },\n },\n});\n\nconst lightTheme = createMuiTheme({\n palette: {\n type: 'light',\n },\n});\n\nconst App = () => {\n const classes = useStyles();\n\n const dispatch = useDispatch();\n let { mainView, loading, darkMode } = useShallowEqualSelector(state => state.appState);\n\n return (\n \n \n \n\n
\n \n {mainView === 'WELCOME' ? : null}\n {mainView === 'MAIN' ?
: null}\n\n \n dispatch(appActions.setDarkMode(!darkMode))}>\n \n \n \n {'© '}\n \n Stefano Brilli\n {' '}\n {new Date().getFullYear()}\n {'.'}\n \n \n Tweet\n \n \n \n \n
\n\n \n \n \n \n \n );\n};\n\nexport default App;\n","import { createWorker, setLogging } from '@ffmpeg/ffmpeg';\nimport { AtracdencProcess } from './atracdenc-worker';\nimport { getPublicPathFor } from '../utils';\nconst AtracdencWorker = require('worker-loader!./atracdenc-worker'); // eslint-disable-line import/no-webpack-loader-syntax\n\ninterface LogPayload {\n message: string;\n action: string;\n}\n\nexport interface AudioExportService {\n init(): Promise;\n export(params: { format: string }): Promise;\n info(): Promise<{ format: string | null; input: string | null }>;\n prepare(file: File): Promise;\n}\n\nexport class FFMpegAudioExportService implements AudioExportService {\n public ffmpegProcess: any;\n public atracdencProcess?: AtracdencProcess;\n public loglines: { action: string; message: string }[] = [];\n public inFileName: string = ``;\n public outFileNameNoExt: string = ``;\n\n async init() {\n setLogging(true);\n }\n\n async prepare(file: File) {\n this.loglines = [];\n this.ffmpegProcess = createWorker({\n logger: (payload: LogPayload) => {\n this.loglines.push(payload);\n console.log(payload.action, payload.message);\n },\n corePath: getPublicPathFor('ffmpeg-core.js'),\n workerPath: getPublicPathFor('worker.min.js'),\n });\n await this.ffmpegProcess.load();\n\n this.atracdencProcess = new AtracdencProcess(new AtracdencWorker());\n await this.atracdencProcess.init();\n\n let ext = file.name.split('.').slice(-1);\n if (ext.length === 0) {\n throw new Error(`Unrecognized file format: ${file.name}`);\n }\n\n this.inFileName = `inAudioFile.${ext[0]}`;\n this.outFileNameNoExt = `outAudioFile`;\n\n await this.ffmpegProcess.write(this.inFileName, file);\n }\n\n async info() {\n await this.ffmpegProcess.transcode(this.inFileName, `${this.outFileNameNoExt}.metadata`, `-f ffmetadata`);\n\n let audioFormatRegex = /Audio:\\s(.*?),/; // Actual content\n let inputFormatRegex = /Input #0,\\s(.*?),/; // Container\n let format: string | null = null;\n let input: string | null = null;\n\n for (let line of this.loglines) {\n let match = line.message.match(audioFormatRegex);\n if (match !== null) {\n format = match[1];\n continue;\n }\n match = line.message.match(inputFormatRegex);\n if (match !== null) {\n input = match[1];\n continue;\n }\n if (format !== null && input !== null) {\n break;\n }\n }\n\n return { format, input };\n }\n\n async export({ format }: { format: string }) {\n if (format === `SP`) {\n const outFileName = `${this.outFileNameNoExt}.raw`;\n await this.ffmpegProcess.transcode(this.inFileName, outFileName, '-f s16be -ar 44100');\n let { data } = await this.ffmpegProcess.read(outFileName);\n return data.buffer;\n } else {\n const outFileName = `${this.outFileNameNoExt}.wav`;\n await this.ffmpegProcess.transcode(this.inFileName, outFileName, '-f wav -ar 44100');\n let { data } = await this.ffmpegProcess.read(outFileName);\n let bitrate: string = `0`;\n switch (format) {\n case `LP2`:\n bitrate = `128`;\n break;\n case `LP105`:\n bitrate = `102`;\n break;\n case `LP4`:\n bitrate = `64`;\n break;\n }\n let result = await this.atracdencProcess!.encode(data.buffer, bitrate);\n return result;\n }\n }\n}\n","/* eslint no-restricted-globals: 0 */\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Provider } from 'react-redux';\nimport * as serviceWorker from './serviceWorker';\nimport { NetMDUSBService } from './services/netmd';\nimport serviceRegistry from './services/registry';\n\nimport { store } from './redux/store';\nimport { actions as appActions } from './redux/app-feature';\n\nimport App from './components/app';\n\nimport './index.css';\nimport { FFMpegAudioExportService } from './services/audio-export';\n\nserviceRegistry.netmdService = new NetMDUSBService();\nserviceRegistry.audioExportService = new FFMpegAudioExportService();\n\n(function setupEventHandlers() {\n window.addEventListener('beforeunload', ev => {\n let isUploading = store.getState().uploadDialog.visible;\n if (!isUploading) {\n return;\n }\n ev.preventDefault();\n ev.returnValue = `Warning! Recording will be interrupted`;\n });\n\n if (navigator && navigator.usb) {\n navigator.usb.ondisconnect = function() {\n store.dispatch(appActions.setState('WELCOME'));\n };\n } else {\n store.dispatch(appActions.setBrowserSupported(false));\n }\n\n // eslint-disable-next-line\n let deferredPrompt: any;\n window.addEventListener('beforeinstallprompt', (e: any) => {\n e.preventDefault();\n deferredPrompt = e;\n });\n})();\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// serviceWorker.unregister();\nserviceWorker.register();\n"],"sourceRoot":""} \ No newline at end of file