diff --git a/src/cdn.nnn.ed.nico/tenjin_pc/assets/ohtomi/src_components_faceRecognition_FaceRecognition_tsx-src_components_shared_organisms_Player_Ove-59cc90.a810eba2a0194c5f16e6.ts b/src/cdn.nnn.ed.nico/tenjin_pc/assets/ohtomi/src_components_faceRecognition_FaceRecognition_tsx-src_components_shared_organisms_Player_Ove-59cc90.a810eba2a0194c5f16e6.ts index 9a001f0..daa1024 100644 --- a/src/cdn.nnn.ed.nico/tenjin_pc/assets/ohtomi/src_components_faceRecognition_FaceRecognition_tsx-src_components_shared_organisms_Player_Ove-59cc90.a810eba2a0194c5f16e6.ts +++ b/src/cdn.nnn.ed.nico/tenjin_pc/assets/ohtomi/src_components_faceRecognition_FaceRecognition_tsx-src_components_shared_organisms_Player_Ove-59cc90.a810eba2a0194c5f16e6.ts @@ -67,778 +67,794 @@ try { "src_components_faceRecognition_FaceRecognition_tsx-src_components_shared_organisms_Player_Ove-59cc90", ], { - 98024: (e, t, n) => { - n.d(t, { B: () => o }); - - function o({ disabled: e = !1, storedDevice: t } = {}) { - const [error, setError] = useState(null); - const [inputDevices, setInputDevices] = useState([]); - const [mediaDeviceInfo, setMediaDeviceInfo] = - useState(); - - const l = useCallback(async () => { - try { - await navigator.mediaDevices - .getUserMedia({ video: !0 }) - .then((mediaStream) => { - // biome-ignore lint/complexity/noForEach: - mediaStream.getTracks().forEach((mediaTrack) => { - mediaStream.removeTrack(mediaTrack), mediaTrack.stop(); - }); - }), - await navigator.mediaDevices - .enumerateDevices() - .then((MediaDevices) => { - setError(null); - - const videoInputDevices = MediaDevices.filter( - (mediaDevice) => - mediaDevice.kind === "videoinput" && - mediaDevice.label !== "", - ); - if ( - (setInputDevices(videoInputDevices), - !mediaDeviceInfo || - !videoInputDevices.some( - (videoInputDevice) => - videoInputDevice.deviceId === - mediaDeviceInfo.deviceId || - videoInputDevice.label === mediaDeviceInfo.label, - )) - ) { - let a; - let r; - const e = - null !== - (a = - null !== - (r = videoInputDevices.find( - ({ deviceId: e }) => - e === (null == t ? void 0 : t.deviceId), - )) && void 0 !== r - ? r - : videoInputDevices.find( - ({ label: e }) => - e === (null == t ? void 0 : t.label), - )) && void 0 !== a - ? a - : videoInputDevices[0]; - if (null == e) - throw new Error("利用可能なカメラデバイスが存在しません"); - setMediaDeviceInfo(e); - } - }); - } catch (e) { - setError(e); - } - }, [ - mediaDeviceInfo, - null == t ? void 0 : t.deviceId, - null == t ? void 0 : t.label, - ]); - - const d = useCallback( - (e) => { - setMediaDeviceInfo( - null == inputDevices - ? void 0 - : inputDevices.find( - (inputDevice) => inputDevice.deviceId === e, - ), - ); - }, - [inputDevices], - ); - - return ( - useEffect( - () => - e - ? (setError(null), - setInputDevices([]), - setMediaDeviceInfo(void 0), - () => {}) - : (l(), - navigator.mediaDevices.addEventListener("devicechange", l), - () => - navigator.mediaDevices.removeEventListener( - "devicechange", - l, - )), - [e, l], - ), - { - error: error, - availableDevices: inputDevices, - currentDevice: mediaDeviceInfo, - select: d, - } - ); - } - }, - 81801: (e, t, n) => { - n.d(t, { y: () => i }); - const o = n(78685); - const r = "camera-device"; - function i() { - const [e, t] = (0, o.A)(r, void 0, { - raw: !1, - serializer: (e) => JSON.stringify(e), - deserializer: (e) => JSON.parse(e), - }); - const n = useCallback((e) => t(e), [t]); - return { device: e, save: n }; - } - }, - 77177: (e, t, n) => { - n.d(t, { j: () => C }); - const o = n(98024); - const r = n(81801); - const i = Math.floor(25.5); // 25 - const s = { width: 440, height: 440, type: "image/jpeg" }; - function c({ status: e, onStatusChanged: t, onCapture: n, onError: c }) { - const { device: storedDevice } = (0, r.y)(); - const { currentDevice } = (0, o.B)({ storedDevice: storedDevice }); - const { captureImage: u } = (({ deviceId: e }) => ({ - captureImage: useCallback( - async ({ - width: outputWidth, - height: outputHeight, - type: outputFormat, - quality: outputQuality, - }: { - // maybe - width: number; - height: number; - type: string; - quality: number; - }) => { - const cameraStream = await navigator.mediaDevices.getUserMedia({ - video: { - deviceId: e ? { exact: e } : void 0, - width: outputWidth, - height: outputHeight, - }, - }); - - const videoTrack = cameraStream.getVideoTracks()[0]; - - if (null == videoTrack) - throw new Error("映像トラックを取得できませんでした"); - - const { width: streamWidth, height: streamHeight } = - videoTrack.getSettings(); - if (null == streamWidth || null == streamHeight) - throw new Error("映像の幅と高さを取得できませんでした"); - - try { - const videoElement = document.createElement("video"); - (videoElement.width = streamWidth), - (videoElement.height = streamHeight), - (videoElement.srcObject = cameraStream), - await videoElement.play(); - - const canvasElement = document.createElement("canvas"); - (canvasElement.width = outputWidth), - (canvasElement.height = outputHeight); - - const canvas2dContext = canvasElement.getContext("2d", { - willReadFrequently: !0, - }); - if (!canvas2dContext) - throw new Error("Canvasの2Dコンテキスト取得に失敗しました"); - - const elapsedTimer = performance.now() + 1e3; - - const halfDimensions = { - x: Math.floor(outputWidth / 2), - y: Math.floor(outputHeight / 2), - }; - - const calculatedCropArea = (( - [streamWidth, streamHeight]: [number, number], - [width, height]: [number, number], - ) => { - const options = { - src: streamWidth / streamHeight, - dest: width / height, - }; - return options.src < options.dest - ? { - x: 0, - y: (streamHeight - streamWidth / options.dest) / 2, - width: streamWidth, - height: streamWidth / options.dest, - } - : { - x: (streamWidth - streamHeight * options.dest) / 2, - y: 0, - width: streamHeight * options.dest, - height: streamHeight, - }; - })([streamWidth, streamHeight], [outputWidth, outputHeight]); - - for (;;) { - if (elapsedTimer <= performance.now()) - throw new Error( - "カメラからの映像を待機する処理がタイムアウトしました", - ); - if ( - (canvas2dContext.drawImage( - videoElement, - calculatedCropArea.x, - calculatedCropArea.y, - calculatedCropArea.width, - calculatedCropArea.height, - ), - Array.from( - canvas2dContext.getImageData( - halfDimensions.x, - halfDimensions.y, - 1, - 1, - ).data, - ) - .slice(0, 3) - .some((e) => i <= e)) - ) - break; - await new Promise((e) => setTimeout(e, 100)); - } - const f = await new Promise((e) => - canvasElement.toBlob(e, outputFormat, outputQuality), - ); - if (!f) throw new Error("Blobデータの生成に失敗しました"); - return f; - } finally { - // biome-ignore lint/complexity/noForEach: - cameraStream.getTracks().forEach((e) => { - e.stop(), cameraStream.removeTrack(e); - }); - } - }, - [e], - ), - }))({ - deviceId: null == currentDevice ? void 0 : currentDevice.deviceId, - }); - const [h, p] = useState(!1); - return ( - useEffect(() => { - null == (null == currentDevice ? void 0 : currentDevice.deviceId) || - "progress" !== e || - h || - u(s) - .then((e) => { - t("success"), n(e); - }) - .catch((e) => { - t("failed"), c(e); - }) - .finally(() => { - p(!0); - }); - }, [ - u, - null == currentDevice ? void 0 : currentDevice.deviceId, - h, - n, - c, - t, - e, - ]), - null - ); - } - const l = n(35830); - const d = n(73305); - const u = n(74848); - function h({ status: e, horizontalAlign: t }) { - return jsxs(p, { - horizontalAlign: t, - children: [ - "failed" !== e && - jsxs(u.Fragment, { - children: [jsx(v, {}), jsx(f, { children: "認証中" })], - }), - "failed" === e && - jsxs(u.Fragment, { - children: [jsx(g, {}), jsx(f, { children: "認証不可" })], - }), - ], - }); - } - const p = l.default.div.withConfig({ componentId: "sc-1rzrjyt-0" })( - [ - "position:fixed;left:", - ";right:", - ";bottom:", - "px;z-index:1;display:inline-flex;padding:", - "px ", - "px;justify-content:center;align-items:center;gap:", - "px;border-radius:99px;color:", - ";background-color:", - ";", - ], - ({ horizontalAlign: e, theme: t }) => - "left" === e ? `${t.space[4]}px` : void 0, - ({ horizontalAlign: e, theme: t }) => - "right" === e ? `${t.space[4]}px` : void 0, - ({ theme: e }) => e.space[4], - ({ theme: e }) => e.space[1], - ({ theme: e }) => e.space[2], - ({ theme: e }) => e.space[1], - ({ theme: e }) => e.colors.white, - ({ theme: e }) => e.colors.transparent.blackClear20, - ); - const f = l.default.div.withConfig({ componentId: "sc-1rzrjyt-1" })( - ["color:", ";font-size:1.2rem;"], - ({ theme: e }) => e.colors.white, - ); - const v = (0, l.default)(d.A) - .attrs({ type: "capture-face-progress", size: "8px" }) - .withConfig({ componentId: "sc-1rzrjyt-2" })( - ["color:", ";"], - ({ theme: e }) => e.colors.accent5, - ); - const g = (0, l.default)(d.A) - .attrs({ type: "capture-face-error", size: "8px" }) - .withConfig({ componentId: "sc-1rzrjyt-3" })( - ["color:", ";"], - ({ theme: e }) => e.colors.warning, - ); - const m = Symbol("result"); - const w = n(71083); - const y = n(53110); - const x = n(78776); - const b = w.A.create({ baseURL: x.A.horusApiEndPoint }); - const k = { - uploadImageAsync: async ({ sessionId: e, image: t }) => { - const n = w.A.toFormData({ image: t }); - return await b - .post(`/sessions/${e}/images/async`, n, { - headers: { "Content-Type": "multipart/form-data" }, - }) - .then((e) => { - return (0, y.F0)(e) - ? ((t = e), { [m]: "failure", error: t }) - : ((e) => ({ [m]: "success", data: e }))(e.data); - let t; - }); - }, - }; - const I = n(80724); - function C({ capture: e, horizontalAlign: t, contextDetail: n }) { - const [i, s] = useState(void 0); - const { device: l } = (0, r.y)(); - const { currentDevice: d, error: p } = (0, o.B)({ storedDevice: l }); - const [f, v] = useState(); - const [g, w] = useState(""); - const y = useRef(!1); - useEffect(() => { - null == i && (null == p ? null != d && s("progress") : s("failed")); - }, [d, p, i]), - useEffect(() => { - switch (i) { - case "progress": - case "success": - null == f && - navigator.mediaDevices - .getUserMedia({ video: !0 }) - .then((e) => v(e)); - } - }, [i, f]), - useEffect( - () => () => { - f && - (f.getTracks().forEach((e) => { - null == f || f.removeTrack(e), e.stop(); - }), - v(void 0)); - }, - [f], - ); - const x = (0, I.R)(); - useEffect(() => { - let e; - (null == (null == d ? void 0 : d.deviceId) && null == p) || - g || - y.current || - ((y.current = !0), - (async (e, t, n) => { - try { - return await e - .postV3RecognitionFacesSession({ camera: t, detail: n }) - .then((e) => { - if (!e.data.recognitionSessionId) throw new Error(); - return e.data.recognitionSessionId; - }); - } catch { - return ""; - } - })( - x, - null !== (e = null == d ? void 0 : d.label) && void 0 !== e - ? e - : "", - n, - ).then((e) => { - w(e), e || s("failed"); - })); - }, [ - x, - n, - null == d ? void 0 : d.deviceId, - null == d ? void 0 : d.label, - p, - g, - ]); - const b = useCallback( - async (e) => { - if (!g) - throw ( - (s("failed"), new Error("本人認証のセッションIDが不正です")) - ); - e && - (await (async (e, t) => { - try { - return await k - .uploadImageAsync({ sessionId: e, image: t }) - .then((e) => ((e) => "success" === e[m])(e)); - } catch { - return !1; - } - })(g, e).then((e) => { - s(e ? "success" : "failed"); - })); - }, - [g], - ); - const C = useCallback(() => {}, []); - const _ = useMemo( - () => - e && "progress" === i && g - ? jsx(c, { - status: i, - onStatusChanged: s, - onCapture: b, - onError: C, - }) - : null, - [e, b, C, g, i], - ); - return jsxs(u.Fragment, { - children: [_, i && jsx(h, { status: i, horizontalAlign: t })], - }); - } - }, - 60616: (e, t, n) => { - n.d(t, { v: () => r }); - const a = n(35830); - const o = n(62851); - const r = (0, a.default)(o.A).withConfig({ componentId: "sc-131fzem-0" })( - ["font-size:40px;opacity:1;&:hover{cursor:pointer;}"], - ); - }, - 21721: (e, t, n) => { - n.d(t, { b: () => p }); - const a = n(63998); - const o = n(35830); - const r: typeof React = n(96540); - const i = n(74848); - const s = ({ rate: e, currentRate: t, onClick: n }) => { - const a = useCallback(() => { - n(e); - }, [e, n]); - const o = Math.abs(e - t) < 0.001; - return jsx(c, { selected: o, onClick: a, children: `x${e}` }); - }; - const c = o.default.button.withConfig({ componentId: "sc-1iiy24x-0" })( - [ - "display:flex;width:48px;height:27px;font-size:13px;font-weight:700;align-items:center;color:", - ";justify-content:center;border-radius:2px;padding:2px;margin:2px;background-color:", - ";border:", - ";&:hover{background-color:", - ";cursor:pointer;}", - ], - ({ theme: e }) => e.colors.white, - ({ theme: e }) => e.colors.black, - ({ selected: e, theme: t }) => - e - ? `2px solid ${t.colors.white}` - : `1px solid ${t.colors.gray.darkness2}`, - ({ theme: e }) => e.colors.primary, - ); - function l({ - currentPlaybackRate: e, - isHover: t, - isOpenRateList: n, - onChangeRateItem: r, - onMouseEnter: c, - onMouseLeave: l, - ...u - }) { - const h = (0, o.useTheme)(); - return jsxs(d, { - width: "108px", - height: "128px", - justifyContent: "center", - py: "2px", - px: "2px", - bg: h.colors.black, - sx: { borderRadius: "4px" }, - onMouseEnter: c, - onMouseLeave: l, - ...u, - $_css: t && n ? "flex" : "none", - children: [ - jsxs(a.so, { - flexDirection: "column", - children: [ - jsx(s, { rate: 1, currentRate: e, onClick: r }), - jsx(s, { rate: 0.75, currentRate: e, onClick: r }), - jsx(s, { rate: 0.5, currentRate: e, onClick: r }), - ], - }), - jsxs(a.so, { - flexDirection: "column", - children: [ - jsx(s, { rate: 1.25, currentRate: e, onClick: r }), - jsx(s, { rate: 1.5, currentRate: e, onClick: r }), - jsx(s, { rate: 1.75, currentRate: e, onClick: r }), - jsx(s, { rate: 2, currentRate: e, onClick: r }), - ], - }), - ], - }); - } - const d = (0, o.default)(a.so).withConfig({ componentId: "sc-v2jbux-0" })( - (e) => ({ display: e.$_css }), - ); - const u = n(60616); - const h = (0, o.default)(u.v).withConfig({ componentId: "sc-16km7w-0" })( - ["color:", ";&:hover{color:", ";}"], - ({ theme: e }) => e.colors.white, - ({ theme: e }) => e.colors.primary, - ); - const p = ({ playbackRate: e, playbackRatesDropdownMenuProps: t }) => { - const { - isHover: n, - isOpenRateList: o, - handleMouseEnter: r, - handleMouseLeave: s, - handleRateItemButton: c, - handleRateIcon: d, - } = t; - return jsxs(a.so, { - sx: { position: "relative" }, - children: [ - jsxs(a.az, { - width: "80px", - height: "80px", - p: 5, - children: [ - jsx(a.az, { - width: "20px", - height: "20px", - sx: { position: "absolute", left: "0", top: "40px" }, - onMouseEnter: r, - onMouseLeave: s, - }), - jsx(h, { - type: `playback-rate-${`${e}`.replace(".", "-")}`, - onClick: d, - onMouseEnter: r, - onMouseLeave: s, - }), - jsx(a.az, { - width: "20px", - height: "20px", - sx: { position: "absolute", right: "0", top: "40px" }, - onMouseEnter: r, - onMouseLeave: s, - }), - ], - }), - jsx(l, { - currentPlaybackRate: e, - isHover: n, - isOpenRateList: o, - onChangeRateItem: c, - onMouseEnter: r, - onMouseLeave: s, - sx: { position: "absolute", left: "-12px", top: "60px" }, - }), - ], - }); - }; - }, - 41233: (e, t, n) => { - n.d(t, { y: () => o }); - const a: typeof React = n(96540); - function o({ changePlaybackRate: e }) { - const [t, n] = useState(!1); - const [o, r] = useState(!1); - return { - isHover: t, - isOpenRateList: o, - handleMouseEnter: useCallback(() => { - n(!0), r(!0); - }, []), - handleMouseLeave: useCallback(() => { - n(!1), r(!1); - }, []), - handleRateItemButton: useCallback( - (t) => { - e(t), r(!1); - }, - [e], - ), - handleRateIcon: useCallback(() => { - r(!0); - }, []), - }; - } - }, - 58169: (e, t, n) => { - n.d(t, { A: () => c }); - const a = n(57097); - const o = n(53110); - const r = n(80724); - const i = n(70195); - const s = n(21137); - const c = () => { - const e = (0, r.R)(); - const { showSnackbar: t } = (0, i.d)(s); - const { mutate: n } = (0, a.n)({ - mutationFn: e.postLearningAmounts, - retry: (e, n) => { - if (e > 2) - return ( - t({ - id: Date.now(), - type: "info", - message: "学習数を記録できませんでした", - actionLabel: "学習数とは", - onClick: () => { - window.open("/help#learning_amount", "_blank", "noopener"); - }, - }), - !1 - ); - const a = !n.response; - const r = n.code === o.pe.ECONNABORTED; - return a || r; - }, - retryDelay: 1e3, - }); - return { addLearningAmounts: n }; - }; - }, - 49474: (e, t, n) => { - n.d(t, { J: () => o }); - const a: typeof React = n(96540); - function o(e) { - const [t, n] = useState("prompt"); - return ( - useEffect(() => { - null != e && - (e - ? navigator.mediaDevices - .getUserMedia({ video: !0 }) - .then((e) => { - e.getTracks().forEach((t) => { - t.stop(), e.removeTrack(t); - }), - n("granted"); - }) - .catch(() => { - n("denied"); - }) - : n("granted")); - }, [e]), - !1 === e || "prompt" !== t - ); - } - }, - 26237: (e, t, n) => { - function a({ - courseId, - chapterId, - materialId, - title, - courseType, - materialType, - }) { - let s; - if (void 0 === courseId && void 0 === chapterId) - (window.dataLayer = - null !== (s = window.dataLayer) && void 0 !== s ? s : []), - window.dataLayer.push({ - event: "video_view", - zane_analytics: { - material_id: String(materialId), - title: title, - content_type: o(courseType), - material_type: materialType, - }, - }); - else if (void 0 === courseId) { - let c; - (window.dataLayer = - null !== (c = window.dataLayer) && void 0 !== c ? c : []), - window.dataLayer.push({ - event: "video_view", - zane_analytics: { - chapter_id: String(chapterId), - material_id: String(materialId), - title: title, - content_type: o(courseType), - material_type: materialType, - }, - }); - } else if (void 0 === chapterId) { - let l; - (window.dataLayer = - null !== (l = window.dataLayer) && void 0 !== l ? l : []), - window.dataLayer.push({ - event: "video_view", - zane_analytics: { - course_id: String(courseId), - material_id: String(materialId), - title: title, - content_type: o(courseType), - material_type: materialType, - }, - }); - } else { - let d; - (window.dataLayer = - null !== (d = window.dataLayer) && void 0 !== d ? d : []), - window.dataLayer.push({ - event: "video_view", - zane_analytics: { - course_id: String(courseId), - chapter_id: String(chapterId), - material_id: String(materialId), - title: title, - content_type: o(courseType), - material_type: materialType, - }, - }); - } - } - function o(e) { - switch (e) { - case "basic": - return "高校必修"; - case "advanced": - return "課外"; - case "zen_univ": - return "大学履修"; - } - } - n.d(t, { d: () => a }); - }, + 98024: setupCameraDevice, + 81801: _81801, + 77177: _77177, + 60616: _60616, + 21721: _21721, + 41233: _41233, + 58169: _58169, + 49474: _49474, + 26237: _26237, }, ]); + +function setupCameraDevice(e, t, n) { + n.d(t, { B: () => setupCameraDeviceImpl }); + + function setupCameraDeviceImpl({ disabled = !1, storedDevice } = {}) { + const [error, setError] = useState(null); + const [inputDevices, setInputDevices] = useState([]); + const [mediaDeviceInfo, setMediaDeviceInfo] = useState(); + + const l = useCallback(async () => { + try { + await navigator.mediaDevices + .getUserMedia({ video: !0 }) + .then((mediaStream) => { + // biome-ignore lint/complexity/noForEach: + mediaStream.getTracks().forEach((mediaTrack) => { + mediaStream.removeTrack(mediaTrack), mediaTrack.stop(); + }); + }), + await navigator.mediaDevices + .enumerateDevices() + .then((MediaDevices) => { + setError(null); + + const videoInputDevices = MediaDevices.filter( + (mediaDevice) => + mediaDevice.kind === "videoinput" && mediaDevice.label !== "", + ); + if ( + (setInputDevices(videoInputDevices), + !mediaDeviceInfo || + !videoInputDevices.some( + (videoInputDevice) => + videoInputDevice.deviceId === mediaDeviceInfo.deviceId || + videoInputDevice.label === mediaDeviceInfo.label, + )) + ) { + let a; + let r; + const e = + null !== + (a = + null !== + (r = videoInputDevices.find( + ({ deviceId: e }) => + e === + (null == storedDevice + ? void 0 + : storedDevice.deviceId), + )) && void 0 !== r + ? r + : videoInputDevices.find( + ({ label: e }) => + e === + (null == storedDevice + ? void 0 + : storedDevice.label), + )) && void 0 !== a + ? a + : videoInputDevices[0]; + if (null == e) + throw new Error("利用可能なカメラデバイスが存在しません"); + setMediaDeviceInfo(e); + } + }); + } catch (e) { + setError(e); + } + }, [ + mediaDeviceInfo, + null == storedDevice ? void 0 : storedDevice.deviceId, + null == storedDevice ? void 0 : storedDevice.label, + ]); + + const d = useCallback( + (e) => { + setMediaDeviceInfo( + null == inputDevices + ? void 0 + : inputDevices.find((inputDevice) => inputDevice.deviceId === e), + ); + }, + [inputDevices], + ); + + return ( + useEffect( + () => + disabled + ? (setError(null), + setInputDevices([]), + setMediaDeviceInfo(void 0), + () => {}) + : (l(), + navigator.mediaDevices.addEventListener("devicechange", l), + () => + navigator.mediaDevices.removeEventListener("devicechange", l)), + [disabled, l], + ), + { + error: error, + availableDevices: inputDevices, + currentDevice: mediaDeviceInfo, + select: d, + } + ); + } +} + +function _81801(e, t, n) { + n.d(t, { y: () => impl }); + const o = n(78685); + const r = "camera-device"; + function impl() { + const [e, t] = (0, o.A)(r, void 0, { + raw: !1, + serializer: (e) => JSON.stringify(e), + deserializer: (e) => JSON.parse(e), + }); + const n = useCallback((e) => t(e), [t]); + return { device: e, save: n }; + } +} + +function _77177(e, t, n) { + n.d(t, { j: () => C }); + const o: typeof setupCameraDevice = n(98024); + const r: typeof _81801 = n(81801); + const i = Math.floor(25.5); // 25 + const s = { width: 440, height: 440, type: "image/jpeg" }; + function c({ status: e, onStatusChanged: t, onCapture: n, onError: c }) { + const { device: storedDevice } = (0, r.y)(); + + // setupCameraDevice + const { currentDevice } = (0, o.B)({ storedDevice: storedDevice }); + const { captureImage } = (({ deviceId }) => ({ + captureImage: useCallback( + async ({ + width: outputWidth, + height: outputHeight, + type: outputFormat, + quality: outputQuality, + }: { + // maybe + width: number; + height: number; + type: string; + quality: number; + }) => { + const cameraStream = await navigator.mediaDevices.getUserMedia({ + video: { + deviceId: deviceId ? { exact: deviceId } : void 0, + width: outputWidth, + height: outputHeight, + }, + }); + + const videoTrack = cameraStream.getVideoTracks()[0]; + + if (null == videoTrack) + throw new Error("映像トラックを取得できませんでした"); + + const { width: streamWidth, height: streamHeight } = + videoTrack.getSettings(); + if (null == streamWidth || null == streamHeight) + throw new Error("映像の幅と高さを取得できませんでした"); + + try { + const videoElement = document.createElement("video"); + (videoElement.width = streamWidth), + (videoElement.height = streamHeight), + (videoElement.srcObject = cameraStream), + await videoElement.play(); + + const canvasElement = document.createElement("canvas"); + (canvasElement.width = outputWidth), + (canvasElement.height = outputHeight); + + const canvas2dContext = canvasElement.getContext("2d", { + willReadFrequently: !0, + }); + if (!canvas2dContext) + throw new Error("Canvasの2Dコンテキスト取得に失敗しました"); + + const elapsedTimer = performance.now() + 1e3; + + const halfDimensions = { + x: Math.floor(outputWidth / 2), + y: Math.floor(outputHeight / 2), + }; + + const calculatedCropArea = (( + [streamWidth, streamHeight]: [number, number], + [width, height]: [number, number], + ) => { + const options = { + src: streamWidth / streamHeight, + dest: width / height, + }; + return options.src < options.dest + ? { + x: 0, + y: (streamHeight - streamWidth / options.dest) / 2, + width: streamWidth, + height: streamWidth / options.dest, + } + : { + x: (streamWidth - streamHeight * options.dest) / 2, + y: 0, + width: streamHeight * options.dest, + height: streamHeight, + }; + })([streamWidth, streamHeight], [outputWidth, outputHeight]); + + for (;;) { + if (elapsedTimer <= performance.now()) + throw new Error( + "カメラからの映像を待機する処理がタイムアウトしました", + ); + if ( + (canvas2dContext.drawImage( + videoElement, + calculatedCropArea.x, + calculatedCropArea.y, + calculatedCropArea.width, + calculatedCropArea.height, + ), + Array.from( + canvas2dContext.getImageData( + halfDimensions.x, + halfDimensions.y, + 1, + 1, + ).data, + ) + .slice(0, 3) + .some((e) => i <= e)) + ) + break; + await new Promise((e) => setTimeout(e, 100)); + } + + const captureImage = await new Promise((res) => + canvasElement.toBlob(res, outputFormat, outputQuality), + ); + if (!captureImage) + throw new Error("Blobデータの生成に失敗しました"); + return captureImage; + } finally { + // biome-ignore lint/complexity/noForEach: + cameraStream.getTracks().forEach((e) => { + e.stop(), cameraStream.removeTrack(e); + }); + } + }, + [deviceId], + ), + }))({ + deviceId: null == currentDevice ? void 0 : currentDevice.deviceId, + }); + const [h, p] = useState(!1); + return ( + useEffect(() => { + null == (null == currentDevice ? void 0 : currentDevice.deviceId) || + "progress" !== e || + h || + captureImage(s) + .then((e) => { + t("success"), n(e); + }) + .catch((e) => { + t("failed"), c(e); + }) + .finally(() => { + p(!0); + }); + }, [ + captureImage, + null == currentDevice ? void 0 : currentDevice.deviceId, + h, + n, + c, + t, + e, + ]), + null + ); + } + const l = n(35830); + const d = n(73305); + const u = n(74848); + function h({ status: e, horizontalAlign: t }) { + return jsxs(p, { + horizontalAlign: t, + children: [ + "failed" !== e && + jsxs(u.Fragment, { + children: [jsx(v, {}), jsx(f, { children: "認証中" })], + }), + "failed" === e && + jsxs(u.Fragment, { + children: [jsx(g, {}), jsx(f, { children: "認証不可" })], + }), + ], + }); + } + const p = l.default.div.withConfig({ componentId: "sc-1rzrjyt-0" })( + [ + "position:fixed;left:", + ";right:", + ";bottom:", + "px;z-index:1;display:inline-flex;padding:", + "px ", + "px;justify-content:center;align-items:center;gap:", + "px;border-radius:99px;color:", + ";background-color:", + ";", + ], + ({ horizontalAlign: e, theme: t }) => + "left" === e ? `${t.space[4]}px` : void 0, + ({ horizontalAlign: e, theme: t }) => + "right" === e ? `${t.space[4]}px` : void 0, + ({ theme: e }) => e.space[4], + ({ theme: e }) => e.space[1], + ({ theme: e }) => e.space[2], + ({ theme: e }) => e.space[1], + ({ theme: e }) => e.colors.white, + ({ theme: e }) => e.colors.transparent.blackClear20, + ); + const f = l.default.div.withConfig({ componentId: "sc-1rzrjyt-1" })( + ["color:", ";font-size:1.2rem;"], + ({ theme: e }) => e.colors.white, + ); + const v = (0, l.default)(d.A) + .attrs({ type: "capture-face-progress", size: "8px" }) + .withConfig({ componentId: "sc-1rzrjyt-2" })( + ["color:", ";"], + ({ theme: e }) => e.colors.accent5, + ); + const g = (0, l.default)(d.A) + .attrs({ type: "capture-face-error", size: "8px" }) + .withConfig({ componentId: "sc-1rzrjyt-3" })( + ["color:", ";"], + ({ theme: e }) => e.colors.warning, + ); + const m = Symbol("result"); + const w = n(71083); + const y = n(53110); + const x = n(78776); + const b = w.A.create({ baseURL: x.A.horusApiEndPoint }); + const k = { + uploadImageAsync: async ({ sessionId: e, image: t }) => { + const n = w.A.toFormData({ image: t }); + return await b + .post(`/sessions/${e}/images/async`, n, { + headers: { "Content-Type": "multipart/form-data" }, + }) + .then((e) => { + return (0, y.F0)(e) + ? ((t = e), { [m]: "failure", error: t }) + : ((e) => ({ [m]: "success", data: e }))(e.data); + let t; + }); + }, + }; + const I = n(80724); + function C({ capture: e, horizontalAlign: t, contextDetail: n }) { + const [i, s] = useState(void 0); + const { device: l } = (0, r.y)(); + const { currentDevice: d, error: p } = (0, o.B)({ storedDevice: l }); + const [f, v] = useState(); + const [g, w] = useState(""); + const y = useRef(!1); + useEffect(() => { + null == i && (null == p ? null != d && s("progress") : s("failed")); + }, [d, p, i]), + useEffect(() => { + switch (i) { + case "progress": + case "success": + null == f && + navigator.mediaDevices + .getUserMedia({ video: !0 }) + .then((e) => v(e)); + } + }, [i, f]), + useEffect( + () => () => { + f && + (f.getTracks().forEach((e) => { + null == f || f.removeTrack(e), e.stop(); + }), + v(void 0)); + }, + [f], + ); + const x = (0, I.R)(); + useEffect(() => { + let e; + (null == (null == d ? void 0 : d.deviceId) && null == p) || + g || + y.current || + ((y.current = !0), + (async (e, t, n) => { + try { + return await e + .postV3RecognitionFacesSession({ camera: t, detail: n }) + .then((e) => { + if (!e.data.recognitionSessionId) throw new Error(); + return e.data.recognitionSessionId; + }); + } catch { + return ""; + } + })( + x, + null !== (e = null == d ? void 0 : d.label) && void 0 !== e ? e : "", + n, + ).then((e) => { + w(e), e || s("failed"); + })); + }, [ + x, + n, + null == d ? void 0 : d.deviceId, + null == d ? void 0 : d.label, + p, + g, + ]); + const b = useCallback( + async (e) => { + if (!g) + throw (s("failed"), new Error("本人認証のセッションIDが不正です")); + e && + (await (async (e, t) => { + try { + return await k + .uploadImageAsync({ sessionId: e, image: t }) + .then((e) => ((e) => "success" === e[m])(e)); + } catch { + return !1; + } + })(g, e).then((e) => { + s(e ? "success" : "failed"); + })); + }, + [g], + ); + const C = useCallback(() => {}, []); + const _ = useMemo( + () => + e && "progress" === i && g + ? jsx(c, { + status: i, + onStatusChanged: s, + onCapture: b, + onError: C, + }) + : null, + [e, b, C, g, i], + ); + return jsxs(u.Fragment, { + children: [_, i && jsx(h, { status: i, horizontalAlign: t })], + }); + } +} + +function _60616(e, t, n) { + n.d(t, { v: () => r }); + const a = n(35830); + const o = n(62851); + const r = (0, a.default)(o.A).withConfig({ componentId: "sc-131fzem-0" })([ + "font-size:40px;opacity:1;&:hover{cursor:pointer;}", + ]); +} + +function _21721(e, t, n) { + n.d(t, { b: () => p }); + const a = n(63998); + const o = n(35830); + const r: typeof React = n(96540); + const i = n(74848); + const s = ({ rate: e, currentRate: t, onClick: n }) => { + const a = useCallback(() => { + n(e); + }, [e, n]); + const o = Math.abs(e - t) < 0.001; + return jsx(c, { selected: o, onClick: a, children: `x${e}` }); + }; + const c = o.default.button.withConfig({ componentId: "sc-1iiy24x-0" })( + [ + "display:flex;width:48px;height:27px;font-size:13px;font-weight:700;align-items:center;color:", + ";justify-content:center;border-radius:2px;padding:2px;margin:2px;background-color:", + ";border:", + ";&:hover{background-color:", + ";cursor:pointer;}", + ], + ({ theme: e }) => e.colors.white, + ({ theme: e }) => e.colors.black, + ({ selected: e, theme: t }) => + e + ? `2px solid ${t.colors.white}` + : `1px solid ${t.colors.gray.darkness2}`, + ({ theme: e }) => e.colors.primary, + ); + function l({ + currentPlaybackRate: e, + isHover: t, + isOpenRateList: n, + onChangeRateItem: r, + onMouseEnter: c, + onMouseLeave: l, + ...u + }) { + const h = (0, o.useTheme)(); + return jsxs(d, { + width: "108px", + height: "128px", + justifyContent: "center", + py: "2px", + px: "2px", + bg: h.colors.black, + sx: { borderRadius: "4px" }, + onMouseEnter: c, + onMouseLeave: l, + ...u, + $_css: t && n ? "flex" : "none", + children: [ + jsxs(a.so, { + flexDirection: "column", + children: [ + jsx(s, { rate: 1, currentRate: e, onClick: r }), + jsx(s, { rate: 0.75, currentRate: e, onClick: r }), + jsx(s, { rate: 0.5, currentRate: e, onClick: r }), + ], + }), + jsxs(a.so, { + flexDirection: "column", + children: [ + jsx(s, { rate: 1.25, currentRate: e, onClick: r }), + jsx(s, { rate: 1.5, currentRate: e, onClick: r }), + jsx(s, { rate: 1.75, currentRate: e, onClick: r }), + jsx(s, { rate: 2, currentRate: e, onClick: r }), + ], + }), + ], + }); + } + const d = (0, o.default)(a.so).withConfig({ componentId: "sc-v2jbux-0" })( + (e) => ({ display: e.$_css }), + ); + const u: typeof _60616 = n(60616); + const h = (0, o.default)(u.v).withConfig({ componentId: "sc-16km7w-0" })( + ["color:", ";&:hover{color:", ";}"], + ({ theme: e }) => e.colors.white, + ({ theme: e }) => e.colors.primary, + ); + const p = ({ playbackRate: e, playbackRatesDropdownMenuProps: t }) => { + const { + isHover: n, + isOpenRateList: o, + handleMouseEnter: r, + handleMouseLeave: s, + handleRateItemButton: c, + handleRateIcon: d, + } = t; + return jsxs(a.so, { + sx: { position: "relative" }, + children: [ + jsxs(a.az, { + width: "80px", + height: "80px", + p: 5, + children: [ + jsx(a.az, { + width: "20px", + height: "20px", + sx: { position: "absolute", left: "0", top: "40px" }, + onMouseEnter: r, + onMouseLeave: s, + }), + jsx(h, { + type: `playback-rate-${`${e}`.replace(".", "-")}`, + onClick: d, + onMouseEnter: r, + onMouseLeave: s, + }), + jsx(a.az, { + width: "20px", + height: "20px", + sx: { position: "absolute", right: "0", top: "40px" }, + onMouseEnter: r, + onMouseLeave: s, + }), + ], + }), + jsx(l, { + currentPlaybackRate: e, + isHover: n, + isOpenRateList: o, + onChangeRateItem: c, + onMouseEnter: r, + onMouseLeave: s, + sx: { position: "absolute", left: "-12px", top: "60px" }, + }), + ], + }); + }; +} + +function _41233(e, t, n) { + n.d(t, { y: () => o }); + const a: typeof React = n(96540); + function o({ changePlaybackRate: e }) { + const [t, n] = useState(!1); + const [o, r] = useState(!1); + return { + isHover: t, + isOpenRateList: o, + handleMouseEnter: useCallback(() => { + n(!0), r(!0); + }, []), + handleMouseLeave: useCallback(() => { + n(!1), r(!1); + }, []), + handleRateItemButton: useCallback( + (t) => { + e(t), r(!1); + }, + [e], + ), + handleRateIcon: useCallback(() => { + r(!0); + }, []), + }; + } +} + +function _58169(e, t, n) { + n.d(t, { A: () => c }); + const a = n(57097); + const o = n(53110); + const r = n(80724); + const i = n(70195); + const s = n(21137); + const c = () => { + const e = (0, r.R)(); + const { showSnackbar: t } = (0, i.d)(s); + const { mutate: n } = (0, a.n)({ + mutationFn: e.postLearningAmounts, + retry: (e, n) => { + if (e > 2) + return ( + t({ + id: Date.now(), + type: "info", + message: "学習数を記録できませんでした", + actionLabel: "学習数とは", + onClick: () => { + window.open("/help#learning_amount", "_blank", "noopener"); + }, + }), + !1 + ); + const a = !n.response; + const r = n.code === o.pe.ECONNABORTED; + return a || r; + }, + retryDelay: 1e3, + }); + return { addLearningAmounts: n }; + }; +} + +function _49474(e, t, n) { + n.d(t, { J: () => o }); + const a: typeof React = n(96540); + function o(e) { + const [t, n] = useState("prompt"); + return ( + useEffect(() => { + null != e && + (e + ? navigator.mediaDevices + .getUserMedia({ video: !0 }) + .then((e) => { + e.getTracks().forEach((t) => { + t.stop(), e.removeTrack(t); + }), + n("granted"); + }) + .catch(() => { + n("denied"); + }) + : n("granted")); + }, [e]), + !1 === e || "prompt" !== t + ); + } +} + +function _26237(e, t, n) { + function a({ + courseId, + chapterId, + materialId, + title, + courseType, + materialType, + }) { + let s; + if (void 0 === courseId && void 0 === chapterId) + (window.dataLayer = + null !== (s = window.dataLayer) && void 0 !== s ? s : []), + window.dataLayer.push({ + event: "video_view", + zane_analytics: { + material_id: String(materialId), + title: title, + content_type: o(courseType), + material_type: materialType, + }, + }); + else if (void 0 === courseId) { + let c; + (window.dataLayer = + null !== (c = window.dataLayer) && void 0 !== c ? c : []), + window.dataLayer.push({ + event: "video_view", + zane_analytics: { + chapter_id: String(chapterId), + material_id: String(materialId), + title: title, + content_type: o(courseType), + material_type: materialType, + }, + }); + } else if (void 0 === chapterId) { + let l; + (window.dataLayer = + null !== (l = window.dataLayer) && void 0 !== l ? l : []), + window.dataLayer.push({ + event: "video_view", + zane_analytics: { + course_id: String(courseId), + material_id: String(materialId), + title: title, + content_type: o(courseType), + material_type: materialType, + }, + }); + } else { + let d; + (window.dataLayer = + null !== (d = window.dataLayer) && void 0 !== d ? d : []), + window.dataLayer.push({ + event: "video_view", + zane_analytics: { + course_id: String(courseId), + chapter_id: String(chapterId), + material_id: String(materialId), + title: title, + content_type: o(courseType), + material_type: materialType, + }, + }); + } + } + function o(e) { + switch (e) { + case "basic": + return "高校必修"; + case "advanced": + return "課外"; + case "zen_univ": + return "大学履修"; + } + } + n.d(t, { d: () => a }); +}