@ledgerhq/device-mockserver-react 0.0.0-delayed-signing-20261113142655
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.MD +202 -0
- package/README.md +48 -0
- package/lib/cjs/index.js +2 -0
- package/lib/cjs/index.js.map +7 -0
- package/lib/cjs/package.json +68 -0
- package/lib/cjs/src/DeviceOsInfo.js +2 -0
- package/lib/cjs/src/DeviceOsInfo.js.map +7 -0
- package/lib/cjs/src/DeviceScreen.js +2 -0
- package/lib/cjs/src/DeviceScreen.js.map +7 -0
- package/lib/cjs/src/DeviceScreenButtons.js +2 -0
- package/lib/cjs/src/DeviceScreenButtons.js.map +7 -0
- package/lib/cjs/src/DeviceScreenImage.js +2 -0
- package/lib/cjs/src/DeviceScreenImage.js.map +7 -0
- package/lib/cjs/src/MockServerDevice.js +2 -0
- package/lib/cjs/src/MockServerDevice.js.map +7 -0
- package/lib/cjs/src/ScreenFrame.js +2 -0
- package/lib/cjs/src/ScreenFrame.js.map +7 -0
- package/lib/cjs/src/deviceModels.js +2 -0
- package/lib/cjs/src/deviceModels.js.map +7 -0
- package/lib/cjs/src/index.js +2 -0
- package/lib/cjs/src/index.js.map +7 -0
- package/lib/cjs/src/webScreenPlatform.js +2 -0
- package/lib/cjs/src/webScreenPlatform.js.map +7 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/index.js.map +7 -0
- package/lib/esm/package.json +68 -0
- package/lib/esm/src/DeviceOsInfo.js +2 -0
- package/lib/esm/src/DeviceOsInfo.js.map +7 -0
- package/lib/esm/src/DeviceScreen.js +2 -0
- package/lib/esm/src/DeviceScreen.js.map +7 -0
- package/lib/esm/src/DeviceScreenButtons.js +2 -0
- package/lib/esm/src/DeviceScreenButtons.js.map +7 -0
- package/lib/esm/src/DeviceScreenImage.js +2 -0
- package/lib/esm/src/DeviceScreenImage.js.map +7 -0
- package/lib/esm/src/MockServerDevice.js +2 -0
- package/lib/esm/src/MockServerDevice.js.map +7 -0
- package/lib/esm/src/ScreenFrame.js +2 -0
- package/lib/esm/src/ScreenFrame.js.map +7 -0
- package/lib/esm/src/deviceModels.js +2 -0
- package/lib/esm/src/deviceModels.js.map +7 -0
- package/lib/esm/src/index.js +2 -0
- package/lib/esm/src/index.js.map +7 -0
- package/lib/esm/src/webScreenPlatform.js +2 -0
- package/lib/esm/src/webScreenPlatform.js.map +7 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/src/DeviceOsInfo.d.ts +12 -0
- package/lib/types/src/DeviceOsInfo.d.ts.map +1 -0
- package/lib/types/src/DeviceScreen.d.ts +17 -0
- package/lib/types/src/DeviceScreen.d.ts.map +1 -0
- package/lib/types/src/DeviceScreenButtons.d.ts +8 -0
- package/lib/types/src/DeviceScreenButtons.d.ts.map +1 -0
- package/lib/types/src/DeviceScreenImage.d.ts +10 -0
- package/lib/types/src/DeviceScreenImage.d.ts.map +1 -0
- package/lib/types/src/MockServerDevice.d.ts +10 -0
- package/lib/types/src/MockServerDevice.d.ts.map +1 -0
- package/lib/types/src/ScreenFrame.d.ts +12 -0
- package/lib/types/src/ScreenFrame.d.ts.map +1 -0
- package/lib/types/src/deviceModels.d.ts +7 -0
- package/lib/types/src/deviceModels.d.ts.map +1 -0
- package/lib/types/src/index.d.ts +5 -0
- package/lib/types/src/index.d.ts.map +1 -0
- package/lib/types/src/webScreenPlatform.d.ts +3 -0
- package/lib/types/src/webScreenPlatform.d.ts.map +1 -0
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -0
- package/package.json +68 -0
- package/tailwind.css +2 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"@ledgerhq/device-mockserver-client": "workspace:*",
|
|
4
|
+
"@ledgerhq/device-mockserver-react-core": "workspace:*"
|
|
5
|
+
},
|
|
6
|
+
"devDependencies": {
|
|
7
|
+
"@ledgerhq/device-management-kit": "workspace:*",
|
|
8
|
+
"@ledgerhq/eslint-config-dsdk": "workspace:*",
|
|
9
|
+
"@ledgerhq/ldmk-tool": "workspace:*",
|
|
10
|
+
"@ledgerhq/lumen-design-core": "0.1.34",
|
|
11
|
+
"@ledgerhq/lumen-ui-react": "0.1.66",
|
|
12
|
+
"@ledgerhq/prettier-config-dsdk": "workspace:*",
|
|
13
|
+
"@ledgerhq/tsconfig-dsdk": "workspace:*",
|
|
14
|
+
"@ledgerhq/vitest-config-dmk": "workspace:*",
|
|
15
|
+
"@types/react": "catalog:",
|
|
16
|
+
"@types/react-dom": "catalog:",
|
|
17
|
+
"react": "catalog:",
|
|
18
|
+
"react-dom": "catalog:"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": "./lib/esm/index.js",
|
|
23
|
+
"require": "./lib/cjs/index.js",
|
|
24
|
+
"types": "./lib/types/index.d.ts"
|
|
25
|
+
},
|
|
26
|
+
"./*": {
|
|
27
|
+
"import": "./lib/esm/*",
|
|
28
|
+
"require": "./lib/cjs/*",
|
|
29
|
+
"types": "./lib/types/*"
|
|
30
|
+
},
|
|
31
|
+
"./tailwind.css": "./tailwind.css"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"./lib",
|
|
35
|
+
"./tailwind.css"
|
|
36
|
+
],
|
|
37
|
+
"license": "Apache-2.0",
|
|
38
|
+
"main": "lib/index.js",
|
|
39
|
+
"name": "@ledgerhq/device-mockserver-react",
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@ledgerhq/device-management-kit": "workspace:*",
|
|
42
|
+
"@ledgerhq/lumen-ui-react": "^0.1.66",
|
|
43
|
+
"react": "catalog:",
|
|
44
|
+
"react-dom": "catalog:"
|
|
45
|
+
},
|
|
46
|
+
"private": false,
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/LedgerHQ/device-sdk-ts.git"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "pnpm ldmk-tool build --entryPoints index.ts,src/*.tsx,src/*.ts --tsconfig tsconfig.prod.json",
|
|
53
|
+
"dev": "concurrently \"pnpm watch:builds\" \"pnpm watch:types\"",
|
|
54
|
+
"lint": "eslint",
|
|
55
|
+
"lint:fix": "pnpm lint --fix",
|
|
56
|
+
"prebuild": "rimraf lib",
|
|
57
|
+
"prettier": "prettier . --check",
|
|
58
|
+
"prettier:fix": "prettier . --write",
|
|
59
|
+
"test": "vitest run",
|
|
60
|
+
"test:coverage": "vitest run --coverage",
|
|
61
|
+
"test:watch": "vitest",
|
|
62
|
+
"typecheck": "tsc --noEmit",
|
|
63
|
+
"watch:builds": "pnpm ldmk-tool watch --entryPoints index.ts,src/*.tsx,src/*.ts --tsconfig tsconfig.prod.json",
|
|
64
|
+
"watch:types": "concurrently \"tsc --watch -p tsconfig.prod.json\" \"tsc-alias --watch -p tsconfig.prod.json\""
|
|
65
|
+
},
|
|
66
|
+
"types": "lib/index.d.ts",
|
|
67
|
+
"version": "0.0.0-delayed-signing-20261113142655"
|
|
68
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e,{useState as b}from"react";import{appIconUrl as u,openableApps as m,useOpenApp as f}from"@ledgerhq/device-mockserver-react-core";import{ScreenFrame as g}from"./ScreenFrame";const w="[&::-webkit-scrollbar]:size-[6px] [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full",p=({name:s})=>{const[n,l]=b(!1);return n?e.createElement("span",{className:"text-muted bg-muted flex size-[12.5cqw] items-center justify-center rounded-full text-[length:6cqw] font-semibold"},s.charAt(0)):e.createElement("img",{src:u(s),alt:"",draggable:!1,className:"size-[12.5cqw] rounded-full",onError:()=>l(!0)})},h=({device:s,model:n,onOpenApp:l})=>{const a=m(s),{opening:o,error:c,open:d}=f(l),r=n.lightScreen?{background:"bg-white",text:"text-black",scrollbar:"[&::-webkit-scrollbar-thumb]:bg-black/30",overlay:"bg-white/70"}:{background:"bg-black",text:"text-white",scrollbar:"[&::-webkit-scrollbar-thumb]:bg-white/30",overlay:"bg-black/70"},i=n.touch?{scroll:"overflow-y-auto",list:"grid grid-cols-3 gap-[1.5cqw]",tile:"min-w-0 py-[3cqw]",opening:"flex-col"}:{scroll:"flex items-center overflow-x-auto",list:"flex gap-[2.5cqw]",tile:"w-[28cqw] shrink-0 py-[1.5cqw]",opening:"flex-row"};return e.createElement("div",{className:"flex flex-col gap-8","data-testid":"container_device-os-info"},e.createElement(g,null,e.createElement("div",{className:`${r.background} ${i.scroll} ${w} ${r.scrollbar} p-[3cqw]`,style:{aspectRatio:n.screenWidth/n.screenHeight},"data-testid":"list_device-apps"},a.length===0?e.createElement("p",{className:`text-[length:5.5cqw] ${r.text} flex h-full w-full items-center justify-center opacity-60`},"No apps installed"):e.createElement("div",{className:i.list},a.map(t=>e.createElement("button",{key:t.name,type:"button",title:`${t.name} ${t.version}`,disabled:!l||o!==void 0,onClick:()=>d(t.name),className:`${r.text} ${i.tile} flex flex-col items-center gap-[1.5cqw] border-0 bg-transparent px-[1.5cqw] disabled:cursor-default enabled:cursor-pointer`,"data-testid":`button_open-app-${t.name}`},e.createElement(p,{name:t.name}),e.createElement("span",{className:"w-full truncate text-center text-[length:4.7cqw] leading-[1.3]"},t.name))))),o!==void 0?e.createElement("div",{className:`${r.text} ${r.overlay} ${i.opening} pointer-events-none absolute inset-0 flex items-center justify-center gap-[3cqw] backdrop-blur-[1cqw]`,"data-testid":"spinner_opening-app-screen"},e.createElement("div",{className:"relative flex size-[18cqw] shrink-0 items-center justify-center"},e.createElement("span",{className:"absolute inset-0 rounded-full border-[0.8cqw] border-current opacity-15"}),e.createElement("span",{className:"absolute inset-0 animate-spin rounded-full border-[0.8cqw] border-transparent border-t-current"}),e.createElement(p,{name:o})),e.createElement("span",{className:"animate-pulse text-[length:4.7cqw] font-semibold"},"Opening ",o)):null),c?e.createElement("p",{className:"body-4 text-error text-center"},c):null)};export{h as DeviceOsInfo};
|
|
2
|
+
//# sourceMappingURL=DeviceOsInfo.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/DeviceOsInfo.tsx"],
|
|
4
|
+
"sourcesContent": ["import React, { useState } from \"react\";\nimport { type Device } from \"@ledgerhq/device-mockserver-client\";\nimport {\n appIconUrl,\n openableApps,\n useOpenApp,\n} from \"@ledgerhq/device-mockserver-react-core\";\n\nimport { type DeviceScreenModel } from \"./deviceModels\";\nimport { ScreenFrame } from \"./ScreenFrame\";\n\n/** A styled scrollbar stays visible where the OS would hide an overlay one. */\nconst SCROLLBAR =\n \"[&::-webkit-scrollbar]:size-[6px] [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full\";\n\ntype AppIconProps = {\n name: string;\n};\n\nconst AppIcon: React.FC<AppIconProps> = ({ name }) => {\n const [missing, setMissing] = useState(false);\n\n if (missing) {\n return (\n <span className=\"text-muted bg-muted flex size-[12.5cqw] items-center justify-center rounded-full text-[length:6cqw] font-semibold\">\n {name.charAt(0)}\n </span>\n );\n }\n\n return (\n <img\n src={appIconUrl(name)}\n alt=\"\"\n draggable={false}\n className=\"size-[12.5cqw] rounded-full\"\n onError={() => setMissing(true)}\n />\n );\n};\n\ntype DeviceOsInfoProps = {\n device: Device;\n model: DeviceScreenModel;\n /** Omitted, the apps are listed but cannot be opened. */\n onOpenApp?: (appName: string) => Promise<void>;\n};\n\nexport const DeviceOsInfo: React.FC<DeviceOsInfoProps> = ({\n device,\n model,\n onOpenApp,\n}) => {\n const apps = openableApps(device);\n const { opening, error, open } = useOpenApp(onOpenApp);\n const screen = model.lightScreen\n ? {\n background: \"bg-white\",\n text: \"text-black\",\n scrollbar: \"[&::-webkit-scrollbar-thumb]:bg-black/30\",\n overlay: \"bg-white/70\",\n }\n : {\n background: \"bg-black\",\n text: \"text-white\",\n scrollbar: \"[&::-webkit-scrollbar-thumb]:bg-white/30\",\n overlay: \"bg-black/70\",\n };\n const layout = model.touch\n ? {\n scroll: \"overflow-y-auto\",\n list: \"grid grid-cols-3 gap-[1.5cqw]\",\n tile: \"min-w-0 py-[3cqw]\",\n opening: \"flex-col\",\n }\n : {\n scroll: \"flex items-center overflow-x-auto\",\n list: \"flex gap-[2.5cqw]\",\n tile: \"w-[28cqw] shrink-0 py-[1.5cqw]\",\n opening: \"flex-row\",\n };\n\n return (\n <div className=\"flex flex-col gap-8\" data-testid=\"container_device-os-info\">\n <ScreenFrame>\n <div\n className={`${screen.background} ${layout.scroll} ${SCROLLBAR} ${screen.scrollbar} p-[3cqw]`}\n style={{ aspectRatio: model.screenWidth / model.screenHeight }}\n data-testid=\"list_device-apps\"\n >\n {apps.length === 0 ? (\n <p\n className={`text-[length:5.5cqw] ${screen.text} flex h-full w-full items-center justify-center opacity-60`}\n >\n No apps installed\n </p>\n ) : (\n <div className={layout.list}>\n {apps.map((app) => (\n <button\n key={app.name}\n type=\"button\"\n title={`${app.name} ${app.version}`}\n disabled={!onOpenApp || opening !== undefined}\n onClick={() => open(app.name)}\n className={`${screen.text} ${layout.tile} flex flex-col items-center gap-[1.5cqw] border-0 bg-transparent px-[1.5cqw] disabled:cursor-default enabled:cursor-pointer`}\n data-testid={`button_open-app-${app.name}`}\n >\n <AppIcon name={app.name} />\n <span className=\"w-full truncate text-center text-[length:4.7cqw] leading-[1.3]\">\n {app.name}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n {opening !== undefined ? (\n <div\n className={`${screen.text} ${screen.overlay} ${layout.opening} pointer-events-none absolute inset-0 flex items-center justify-center gap-[3cqw] backdrop-blur-[1cqw]`}\n data-testid=\"spinner_opening-app-screen\"\n >\n <div className=\"relative flex size-[18cqw] shrink-0 items-center justify-center\">\n <span className=\"absolute inset-0 rounded-full border-[0.8cqw] border-current opacity-15\" />\n <span className=\"absolute inset-0 animate-spin rounded-full border-[0.8cqw] border-transparent border-t-current\" />\n <AppIcon name={opening} />\n </div>\n <span className=\"animate-pulse text-[length:4.7cqw] font-semibold\">\n Opening {opening}\n </span>\n </div>\n ) : null}\n </ScreenFrame>\n {error ? <p className=\"body-4 text-error text-center\">{error}</p> : null}\n </div>\n );\n};\n"],
|
|
5
|
+
"mappings": "AAAA,OAAOA,GAAS,YAAAC,MAAgB,QAEhC,OACE,cAAAC,EACA,gBAAAC,EACA,cAAAC,MACK,yCAGP,OAAS,eAAAC,MAAmB,gBAG5B,MAAMC,EACJ,0HAMIC,EAAkC,CAAC,CAAE,KAAAC,CAAK,IAAM,CACpD,KAAM,CAACC,EAASC,CAAU,EAAIT,EAAS,EAAK,EAE5C,OAAIQ,EAEAT,EAAA,cAAC,QAAK,UAAU,qHACbQ,EAAK,OAAO,CAAC,CAChB,EAKFR,EAAA,cAAC,OACC,IAAKE,EAAWM,CAAI,EACpB,IAAI,GACJ,UAAW,GACX,UAAU,8BACV,QAAS,IAAME,EAAW,EAAI,EAChC,CAEJ,EASaC,EAA4C,CAAC,CACxD,OAAAC,EACA,MAAAC,EACA,UAAAC,CACF,IAAM,CACJ,MAAMC,EAAOZ,EAAaS,CAAM,EAC1B,CAAE,QAAAI,EAAS,MAAAC,EAAO,KAAAC,CAAK,EAAId,EAAWU,CAAS,EAC/CK,EAASN,EAAM,YACjB,CACE,WAAY,WACZ,KAAM,aACN,UAAW,2CACX,QAAS,aACX,EACA,CACE,WAAY,WACZ,KAAM,aACN,UAAW,2CACX,QAAS,aACX,EACEO,EAASP,EAAM,MACjB,CACE,OAAQ,kBACR,KAAM,gCACN,KAAM,oBACN,QAAS,UACX,EACA,CACE,OAAQ,oCACR,KAAM,oBACN,KAAM,iCACN,QAAS,UACX,EAEJ,OACEb,EAAA,cAAC,OAAI,UAAU,sBAAsB,cAAY,4BAC/CA,EAAA,cAACK,EAAA,KACCL,EAAA,cAAC,OACC,UAAW,GAAGmB,EAAO,UAAU,IAAIC,EAAO,MAAM,IAAId,CAAS,IAAIa,EAAO,SAAS,YACjF,MAAO,CAAE,YAAaN,EAAM,YAAcA,EAAM,YAAa,EAC7D,cAAY,oBAEXE,EAAK,SAAW,EACff,EAAA,cAAC,KACC,UAAW,wBAAwBmB,EAAO,IAAI,8DAC/C,mBAED,EAEAnB,EAAA,cAAC,OAAI,UAAWoB,EAAO,MACpBL,EAAK,IAAKM,GACTrB,EAAA,cAAC,UACC,IAAKqB,EAAI,KACT,KAAK,SACL,MAAO,GAAGA,EAAI,IAAI,IAAIA,EAAI,OAAO,GACjC,SAAU,CAACP,GAAaE,IAAY,OACpC,QAAS,IAAME,EAAKG,EAAI,IAAI,EAC5B,UAAW,GAAGF,EAAO,IAAI,IAAIC,EAAO,IAAI,8HACxC,cAAa,mBAAmBC,EAAI,IAAI,IAExCrB,EAAA,cAACO,EAAA,CAAQ,KAAMc,EAAI,KAAM,EACzBrB,EAAA,cAAC,QAAK,UAAU,kEACbqB,EAAI,IACP,CACF,CACD,CACH,CAEJ,EACCL,IAAY,OACXhB,EAAA,cAAC,OACC,UAAW,GAAGmB,EAAO,IAAI,IAAIA,EAAO,OAAO,IAAIC,EAAO,OAAO,yGAC7D,cAAY,8BAEZpB,EAAA,cAAC,OAAI,UAAU,mEACbA,EAAA,cAAC,QAAK,UAAU,0EAA0E,EAC1FA,EAAA,cAAC,QAAK,UAAU,iGAAiG,EACjHA,EAAA,cAACO,EAAA,CAAQ,KAAMS,EAAS,CAC1B,EACAhB,EAAA,cAAC,QAAK,UAAU,oDAAmD,WACxDgB,CACX,CACF,EACE,IACN,EACCC,EAAQjB,EAAA,cAAC,KAAE,UAAU,iCAAiCiB,CAAM,EAAO,IACtE,CAEJ",
|
|
6
|
+
"names": ["React", "useState", "appIconUrl", "openableApps", "useOpenApp", "ScreenFrame", "SCROLLBAR", "AppIcon", "name", "missing", "setMissing", "DeviceOsInfo", "device", "model", "onOpenApp", "apps", "opening", "error", "open", "screen", "layout", "app"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e,{useEffect as z,useRef as h,useState as b}from"react";import{useScreenPolling as N}from"@ledgerhq/device-mockserver-react-core";import{Banner as P,IconButton as _}from"@ledgerhq/lumen-ui-react";import{ChevronDown as H,ChevronUp as I}from"@ledgerhq/lumen-ui-react/symbols";import{findDeviceScreenModel as W}from"./deviceModels";import{DeviceOsInfo as A}from"./DeviceOsInfo";import{DeviceScreenButtons as B}from"./DeviceScreenButtons";import{DeviceScreenImage as F}from"./DeviceScreenImage";import{ScreenFrame as L}from"./ScreenFrame";import{webScreenPlatform as X}from"./webScreenPlatform";const v=16,k=224,U=200,D=(o,n,c)=>{const s=(l,i)=>Math.min(Math.max(l,0),Math.max(i,0));return{left:s(o,window.innerWidth-c.width),top:s(n,window.innerHeight-c.height)}},$=(o,n)=>n?`${o} - ${n}`:o,ee=({api:o,deviceType:n,firmwareVersion:c,floating:s=!1,defaultCollapsed:l=!1})=>{const i=W(n),[m,a]=b(l),g=N(o,!s||!m,X);return s?e.createElement(O,{title:$(i.label,c),model:i,collapsed:m,onToggle:()=>a(f=>!f)},S(g,i,o)):e.createElement("div",{className:"mx-auto flex w-full max-w-[420px] flex-col gap-8","data-testid":"container_device-screen"},S(g,i,o))},O=({title:o,model:n,collapsed:c,onToggle:s,children:l})=>{const i=h(null),[m,a]=b(),[g,f]=b(k),d=h(null),u=h(null);z(()=>{const t=()=>{const r=i.current?.getBoundingClientRect();r&&a(p=>p&&D(p.left,p.top,r))};return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[]);const M=t=>{const r=i.current?.getBoundingClientRect();!r||t.button!==0||t.target.closest("button")||(t.currentTarget.setPointerCapture(t.pointerId),d.current={dx:t.clientX-r.left,dy:t.clientY-r.top})},y=t=>{const r=i.current?.getBoundingClientRect();!d.current||!r||a(D(t.clientX-d.current.dx,t.clientY-d.current.dy,r))},w=()=>{d.current=null},C=t=>{const r=i.current?.getBoundingClientRect();!r||t.button!==0||(t.currentTarget.setPointerCapture(t.pointerId),a({left:r.left,top:r.top}),u.current={x:t.clientX,width:r.width})},E=t=>{const r=i.current?.getBoundingClientRect();if(!u.current||!r)return;const p=u.current.width+t.clientX-u.current.x,T=window.innerWidth-r.left-v;f(Math.max(U,Math.min(p,T)))},x=()=>{u.current=null};return e.createElement("div",{ref:i,className:"bg-base border-muted fixed flex max-w-[calc(100vw-32px)] flex-col rounded-lg border shadow-lg",style:{zIndex:1e3,width:g,...m??{right:v,bottom:v}},"data-testid":"container_device-screen"},e.createElement("div",{className:"flex cursor-move items-center gap-8 px-12 py-8 select-none",style:{touchAction:"none"},onPointerDown:M,onPointerMove:y,onPointerUp:w,onPointerCancel:w},e.createElement(n.icon,{size:16}),e.createElement("span",{className:"body-3-semi-bold text-base flex-1"},o),e.createElement(_,{appearance:"no-background",size:"xs",icon:c?I:H,"aria-label":c?"Expand device screen":"Collapse device screen",onClick:s,"data-testid":"button_toggle-device-screen"})),c?null:e.createElement(e.Fragment,null,e.createElement("div",{className:"flex flex-col gap-8 px-12 pb-12"},l),e.createElement("div",{className:"group absolute top-0 right-[-6px] bottom-0 flex w-[12px] cursor-ew-resize items-center justify-center",style:{touchAction:"none"},onPointerDown:C,onPointerMove:E,onPointerUp:x,onPointerCancel:x,"aria-hidden":!0,"data-testid":"handle_resize-device-screen"},e.createElement("span",{className:"border-muted bg-base group-hover:bg-muted group-active:bg-muted h-40 w-[6px] rounded-full border transition-colors"}))))};function S(o,n,c){switch(o.kind){case"loading":return e.createElement(L,null,e.createElement("div",{className:`${n.lightScreen?"bg-white text-black":"bg-black text-white"} flex items-center justify-center`,style:{aspectRatio:n.screenWidth/n.screenHeight},"data-testid":"placeholder_device-screen-loading"},e.createElement("span",{className:"animate-pulse opacity-60"},e.createElement(n.icon,{size:32}))));case"error":return e.createElement(P,{appearance:"error",title:"Screen unavailable",description:o.message});case"os-info":return e.createElement(e.Fragment,null,e.createElement(A,{device:o.device,model:n,onOpenApp:n.speculos?c.openApp:void 0}),n.speculos?null:e.createElement(P,{appearance:"info",title:"No screen to capture",description:`Speculos has no emulator for the ${n.label}, so this device is mocked all the way through and has no screen.`,"data-testid":"banner_device-screen-no-emulator"}));case"image":return e.createElement(e.Fragment,null,e.createElement(F,{src:o.src,onTouch:n.touch?o.input.touch:void 0}),n.touch?null:e.createElement(B,{onPress:o.input.pressButton}))}}export{ee as DeviceScreen};
|
|
2
|
+
//# sourceMappingURL=DeviceScreen.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/DeviceScreen.tsx"],
|
|
4
|
+
"sourcesContent": ["import React, { useEffect, useRef, useState } from \"react\";\nimport {\n type DeviceScreenState,\n type ScreenApi,\n useScreenPolling,\n} from \"@ledgerhq/device-mockserver-react-core\";\nimport { Banner, IconButton } from \"@ledgerhq/lumen-ui-react\";\nimport { ChevronDown, ChevronUp } from \"@ledgerhq/lumen-ui-react/symbols\";\n\nimport { type DeviceScreenModel, findDeviceScreenModel } from \"./deviceModels\";\nimport { DeviceOsInfo } from \"./DeviceOsInfo\";\nimport { DeviceScreenButtons } from \"./DeviceScreenButtons\";\nimport { DeviceScreenImage } from \"./DeviceScreenImage\";\nimport { ScreenFrame } from \"./ScreenFrame\";\nimport { webScreenPlatform } from \"./webScreenPlatform\";\n\nexport type DeviceScreenProps = {\n api: ScreenApi;\n /** The mock server's `device_type`, a DMK `DeviceModelId`. */\n deviceType: string;\n /** Shown next to the model name in the floating window's header. */\n firmwareVersion?: string;\n /**\n * Render as a window over the page that can be dragged by its header and\n * collapsed to it, rather than inline where it is placed.\n */\n floating?: boolean;\n defaultCollapsed?: boolean;\n};\n\ninterface Position {\n readonly left: number;\n readonly top: number;\n}\n\nconst EDGE_MARGIN_PX = 16;\nconst DEFAULT_WIDTH_PX = 224;\nconst MIN_WIDTH_PX = 200;\n\n/** Keeps the whole window, header included, where it can be dragged back. */\nconst clampToViewport = (\n left: number,\n top: number,\n rect: DOMRect,\n): Position => {\n const clamp = (value: number, max: number) =>\n Math.min(Math.max(value, 0), Math.max(max, 0));\n return {\n left: clamp(left, window.innerWidth - rect.width),\n top: clamp(top, window.innerHeight - rect.height),\n };\n};\n\nconst deviceScreenTitle = (label: string, firmwareVersion?: string) =>\n firmwareVersion ? `${label} - ${firmwareVersion}` : label;\n\nexport const DeviceScreen: React.FC<DeviceScreenProps> = ({\n api,\n deviceType,\n firmwareVersion,\n floating = false,\n defaultCollapsed = false,\n}) => {\n const model = findDeviceScreenModel(deviceType);\n const [collapsed, setCollapsed] = useState(defaultCollapsed);\n const state = useScreenPolling(\n api,\n !floating || !collapsed,\n webScreenPlatform,\n );\n\n if (!floating) {\n return (\n <div\n className=\"mx-auto flex w-full max-w-[420px] flex-col gap-8\"\n data-testid=\"container_device-screen\"\n >\n {renderScreen(state, model, api)}\n </div>\n );\n }\n\n return (\n <FloatingWindow\n title={deviceScreenTitle(model.label, firmwareVersion)}\n model={model}\n collapsed={collapsed}\n onToggle={() => setCollapsed((value) => !value)}\n >\n {renderScreen(state, model, api)}\n </FloatingWindow>\n );\n};\n\ntype FloatingWindowProps = {\n title: string;\n model: DeviceScreenModel;\n collapsed: boolean;\n onToggle: () => void;\n children: React.ReactNode;\n};\n\nconst FloatingWindow: React.FC<FloatingWindowProps> = ({\n title,\n model,\n collapsed,\n onToggle,\n children,\n}) => {\n const windowRef = useRef<HTMLDivElement>(null);\n /** Unset until first dragged: the window starts in the bottom right corner. */\n const [position, setPosition] = useState<Position>();\n const [width, setWidth] = useState(DEFAULT_WIDTH_PX);\n const drag = useRef<{ dx: number; dy: number } | null>(null);\n const resize = useRef<{ x: number; width: number } | null>(null);\n\n // Once moved, the window holds fixed coordinates that a shrinking viewport\n // could leave off-screen.\n useEffect(() => {\n const handleViewportResize = () => {\n const rect = windowRef.current?.getBoundingClientRect();\n if (!rect) return;\n setPosition(\n (current) =>\n current && clampToViewport(current.left, current.top, rect),\n );\n };\n window.addEventListener(\"resize\", handleViewportResize);\n return () => window.removeEventListener(\"resize\", handleViewportResize);\n }, []);\n\n const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n const rect = windowRef.current?.getBoundingClientRect();\n // A drag captures the pointer, which would steal the button's click.\n if (\n !rect ||\n event.button !== 0 ||\n (event.target as HTMLElement).closest(\"button\")\n ) {\n return;\n }\n event.currentTarget.setPointerCapture(event.pointerId);\n drag.current = {\n dx: event.clientX - rect.left,\n dy: event.clientY - rect.top,\n };\n };\n\n const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const rect = windowRef.current?.getBoundingClientRect();\n if (!drag.current || !rect) return;\n setPosition(\n clampToViewport(\n event.clientX - drag.current.dx,\n event.clientY - drag.current.dy,\n rect,\n ),\n );\n };\n\n const handlePointerUp = () => {\n drag.current = null;\n };\n\n const handleResizeDown = (event: React.PointerEvent<HTMLDivElement>) => {\n const rect = windowRef.current?.getBoundingClientRect();\n if (!rect || event.button !== 0) return;\n event.currentTarget.setPointerCapture(event.pointerId);\n // Pin the top left corner, or growing would push the window leftwards\n // while it is still anchored to the bottom right.\n setPosition({ left: rect.left, top: rect.top });\n resize.current = { x: event.clientX, width: rect.width };\n };\n\n const handleResizeMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const rect = windowRef.current?.getBoundingClientRect();\n if (!resize.current || !rect) return;\n const next = resize.current.width + event.clientX - resize.current.x;\n const max = window.innerWidth - rect.left - EDGE_MARGIN_PX;\n setWidth(Math.max(MIN_WIDTH_PX, Math.min(next, max)));\n };\n\n const handleResizeUp = () => {\n resize.current = null;\n };\n\n return (\n <div\n ref={windowRef}\n className=\"bg-base border-muted fixed flex max-w-[calc(100vw-32px)] flex-col rounded-lg border shadow-lg\"\n style={{\n zIndex: 1000,\n width,\n ...(position ?? { right: EDGE_MARGIN_PX, bottom: EDGE_MARGIN_PX }),\n }}\n data-testid=\"container_device-screen\"\n >\n <div\n className=\"flex cursor-move items-center gap-8 px-12 py-8 select-none\"\n style={{ touchAction: \"none\" }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n <model.icon size={16} />\n <span className=\"body-3-semi-bold text-base flex-1\">{title}</span>\n <IconButton\n appearance=\"no-background\"\n size=\"xs\"\n icon={collapsed ? ChevronUp : ChevronDown}\n aria-label={\n collapsed ? \"Expand device screen\" : \"Collapse device screen\"\n }\n onClick={onToggle}\n data-testid=\"button_toggle-device-screen\"\n />\n </div>\n {collapsed ? null : (\n <>\n <div className=\"flex flex-col gap-8 px-12 pb-12\">{children}</div>\n <div\n className=\"group absolute top-0 right-[-6px] bottom-0 flex w-[12px] cursor-ew-resize items-center justify-center\"\n style={{ touchAction: \"none\" }}\n onPointerDown={handleResizeDown}\n onPointerMove={handleResizeMove}\n onPointerUp={handleResizeUp}\n onPointerCancel={handleResizeUp}\n aria-hidden\n data-testid=\"handle_resize-device-screen\"\n >\n <span className=\"border-muted bg-base group-hover:bg-muted group-active:bg-muted h-40 w-[6px] rounded-full border transition-colors\" />\n </div>\n </>\n )}\n </div>\n );\n};\n\nfunction renderScreen(\n state: DeviceScreenState,\n model: DeviceScreenModel,\n api: ScreenApi,\n) {\n switch (state.kind) {\n case \"loading\":\n return (\n <ScreenFrame>\n <div\n className={`${model.lightScreen ? \"bg-white text-black\" : \"bg-black text-white\"} flex items-center justify-center`}\n style={{ aspectRatio: model.screenWidth / model.screenHeight }}\n data-testid=\"placeholder_device-screen-loading\"\n >\n <span className=\"animate-pulse opacity-60\">\n <model.icon size={32} />\n </span>\n </div>\n </ScreenFrame>\n );\n case \"error\":\n return (\n <Banner\n appearance=\"error\"\n title=\"Screen unavailable\"\n description={state.message}\n />\n );\n case \"os-info\":\n return (\n <>\n <DeviceOsInfo\n device={state.device}\n model={model}\n onOpenApp={model.speculos ? api.openApp : undefined}\n />\n {model.speculos ? null : (\n <Banner\n appearance=\"info\"\n title=\"No screen to capture\"\n description={`Speculos has no emulator for the ${model.label}, so this device is mocked all the way through and has no screen.`}\n data-testid=\"banner_device-screen-no-emulator\"\n />\n )}\n </>\n );\n case \"image\":\n return (\n <>\n <DeviceScreenImage\n src={state.src}\n onTouch={model.touch ? state.input.touch : undefined}\n />\n {model.touch ? null : (\n <DeviceScreenButtons onPress={state.input.pressButton} />\n )}\n </>\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["React", "useEffect", "useRef", "useState", "useScreenPolling", "Banner", "IconButton", "ChevronDown", "ChevronUp", "findDeviceScreenModel", "DeviceOsInfo", "DeviceScreenButtons", "DeviceScreenImage", "ScreenFrame", "webScreenPlatform", "EDGE_MARGIN_PX", "DEFAULT_WIDTH_PX", "MIN_WIDTH_PX", "clampToViewport", "left", "top", "rect", "clamp", "value", "max", "deviceScreenTitle", "label", "firmwareVersion", "DeviceScreen", "api", "deviceType", "floating", "defaultCollapsed", "model", "collapsed", "setCollapsed", "state", "FloatingWindow", "renderScreen", "title", "onToggle", "children", "windowRef", "position", "setPosition", "width", "setWidth", "drag", "resize", "handleViewportResize", "current", "handlePointerDown", "event", "handlePointerMove", "handlePointerUp", "handleResizeDown", "handleResizeMove", "next", "handleResizeUp"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import s from"react";import{useButtonHold as c}from"@ledgerhq/device-mockserver-react-core";const a=[{button:"left",label:"Left"},{button:"both",label:"Both"},{button:"right",label:"Right"}],u=e=>e===" "||e==="Enter",b=({onPress:e})=>{const{hold:r,release:n}=c(e);return s.createElement("div",{className:"flex gap-8"},a.map(({button:o,label:i})=>s.createElement("button",{key:o,type:"button","aria-label":`${i} button`,onPointerDown:t=>{t.button===0&&(t.currentTarget.setPointerCapture(t.pointerId),r(o))},onPointerUp:n,onPointerCancel:n,onKeyDown:t=>{u(t.key)&&(t.preventDefault(),r(o))},onKeyUp:t=>u(t.key)&&n(),className:"border-muted body-3 text-base bg-muted hover:bg-muted-pressed active:bg-active flex-1 rounded-md border py-8 select-none",style:{touchAction:"none"},"data-testid":`button_device-screen-${o}`},i)))};export{b as DeviceScreenButtons};
|
|
2
|
+
//# sourceMappingURL=DeviceScreenButtons.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/DeviceScreenButtons.tsx"],
|
|
4
|
+
"sourcesContent": ["import React from \"react\";\nimport {\n type SpeculosAction,\n type SpeculosButton,\n} from \"@ledgerhq/device-mockserver-client\";\nimport { useButtonHold } from \"@ledgerhq/device-mockserver-react-core\";\n\nconst BUTTONS: { button: SpeculosButton; label: string }[] = [\n { button: \"left\", label: \"Left\" },\n { button: \"both\", label: \"Both\" },\n { button: \"right\", label: \"Right\" },\n];\n\nconst isActivationKey = (key: string) => key === \" \" || key === \"Enter\";\n\ntype DeviceScreenButtonsProps = {\n onPress: (button: SpeculosButton, action: SpeculosAction) => void;\n};\n\nexport const DeviceScreenButtons: React.FC<DeviceScreenButtonsProps> = ({\n onPress,\n}) => {\n const { hold, release } = useButtonHold(onPress);\n\n // Plain buttons: Lumen's Button does not report press and release apart,\n // and a hold needs both.\n return (\n <div className=\"flex gap-8\">\n {BUTTONS.map(({ button, label }) => (\n <button\n key={button}\n type=\"button\"\n aria-label={`${label} button`}\n onPointerDown={(event) => {\n if (event.button !== 0) return;\n // Capture so the release still arrives if the pointer wanders off.\n event.currentTarget.setPointerCapture(event.pointerId);\n hold(button);\n }}\n onPointerUp={release}\n onPointerCancel={release}\n // Keyboard activation fires no pointer events.\n onKeyDown={(event) => {\n if (!isActivationKey(event.key)) return;\n event.preventDefault();\n hold(button);\n }}\n onKeyUp={(event) => isActivationKey(event.key) && release()}\n className=\"border-muted body-3 text-base bg-muted hover:bg-muted-pressed active:bg-active flex-1 rounded-md border py-8 select-none\"\n style={{ touchAction: \"none\" }}\n data-testid={`button_device-screen-${button}`}\n >\n {label}\n </button>\n ))}\n </div>\n );\n};\n"],
|
|
5
|
+
"mappings": "AAAA,OAAOA,MAAW,QAKlB,OAAS,iBAAAC,MAAqB,yCAE9B,MAAMC,EAAuD,CAC3D,CAAE,OAAQ,OAAQ,MAAO,MAAO,EAChC,CAAE,OAAQ,OAAQ,MAAO,MAAO,EAChC,CAAE,OAAQ,QAAS,MAAO,OAAQ,CACpC,EAEMC,EAAmBC,GAAgBA,IAAQ,KAAOA,IAAQ,QAMnDC,EAA0D,CAAC,CACtE,QAAAC,CACF,IAAM,CACJ,KAAM,CAAE,KAAAC,EAAM,QAAAC,CAAQ,EAAIP,EAAcK,CAAO,EAI/C,OACEN,EAAA,cAAC,OAAI,UAAU,cACZE,EAAQ,IAAI,CAAC,CAAE,OAAAO,EAAQ,MAAAC,CAAM,IAC5BV,EAAA,cAAC,UACC,IAAKS,EACL,KAAK,SACL,aAAY,GAAGC,CAAK,UACpB,cAAgBC,GAAU,CACpBA,EAAM,SAAW,IAErBA,EAAM,cAAc,kBAAkBA,EAAM,SAAS,EACrDJ,EAAKE,CAAM,EACb,EACA,YAAaD,EACb,gBAAiBA,EAEjB,UAAYG,GAAU,CACfR,EAAgBQ,EAAM,GAAG,IAC9BA,EAAM,eAAe,EACrBJ,EAAKE,CAAM,EACb,EACA,QAAUE,GAAUR,EAAgBQ,EAAM,GAAG,GAAKH,EAAQ,EAC1D,UAAU,2HACV,MAAO,CAAE,YAAa,MAAO,EAC7B,cAAa,wBAAwBC,CAAM,IAE1CC,CACH,CACD,CACH,CAEJ",
|
|
6
|
+
"names": ["React", "useButtonHold", "BUTTONS", "isActivationKey", "key", "DeviceScreenButtons", "onPress", "hold", "release", "button", "label", "event"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import c,{useCallback as p,useEffect as f,useRef as h,useState as b}from"react";import{toScreenPoint as P,useTouchHold as S}from"@ledgerhq/device-mockserver-react-core";import{ScreenFrame as v}from"./ScreenFrame";const D=({src:a,onTouch:n})=>{const r=h(null),[m,i]=b(!1),s=S(n);f(()=>i(!1),[a]);const u=e=>{const t=r.current;if(!n||!t||e.button!==0)return;const o=t.getBoundingClientRect(),d=P(e.clientX-o.left,e.clientY-o.top,o,{width:t.naturalWidth,height:t.naturalHeight});d&&s.hold(d)&&t.setPointerCapture(e.pointerId)},l=e=>{s.release()&&r.current?.releasePointerCapture(e.pointerId)},g=p(()=>i(!0),[]);return m?c.createElement("p",{className:"body-4 text-error text-center","data-testid":"text_device-screen-undecodable"},"Screenshot could not be decoded"):c.createElement(v,null,c.createElement("img",{ref:r,src:a,alt:"Device screen",draggable:!1,onError:g,onPointerDown:u,onPointerUp:l,onPointerCancel:l,className:`block w-full bg-black select-none ${n?"cursor-pointer":""}`,style:{imageRendering:"pixelated",touchAction:"none"},"data-testid":"image_device-screen"}))};export{D as DeviceScreenImage};
|
|
2
|
+
//# sourceMappingURL=DeviceScreenImage.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/DeviceScreenImage.tsx"],
|
|
4
|
+
"sourcesContent": ["import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { type SpeculosAction } from \"@ledgerhq/device-mockserver-client\";\nimport {\n toScreenPoint,\n useTouchHold,\n} from \"@ledgerhq/device-mockserver-react-core\";\n\nimport { ScreenFrame } from \"./ScreenFrame\";\n\ntype DeviceScreenImageProps = {\n src: string;\n /** Omitted for a button-driven device. */\n onTouch?: (x: number, y: number, action: SpeculosAction) => void;\n};\n\nexport const DeviceScreenImage: React.FC<DeviceScreenImageProps> = ({\n src,\n onTouch,\n}) => {\n const imageRef = useRef<HTMLImageElement>(null);\n const [undecodable, setUndecodable] = useState(false);\n const touch = useTouchHold(onTouch);\n\n useEffect(() => setUndecodable(false), [src]);\n\n const handlePointerDown = (event: React.PointerEvent<HTMLImageElement>) => {\n const image = imageRef.current;\n if (!onTouch || !image || event.button !== 0) return;\n const rect = image.getBoundingClientRect();\n const point = toScreenPoint(\n event.clientX - rect.left,\n event.clientY - rect.top,\n rect,\n { width: image.naturalWidth, height: image.naturalHeight },\n );\n // Capture so the release still arrives if the pointer wanders off the\n // image mid-hold; without it the device would stay pressed forever.\n if (point && touch.hold(point)) {\n image.setPointerCapture(event.pointerId);\n }\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLImageElement>) => {\n if (touch.release()) {\n imageRef.current?.releasePointerCapture(event.pointerId);\n }\n };\n\n const handleError = useCallback(() => setUndecodable(true), []);\n\n if (undecodable) {\n return (\n <p\n className=\"body-4 text-error text-center\"\n data-testid=\"text_device-screen-undecodable\"\n >\n Screenshot could not be decoded\n </p>\n );\n }\n\n return (\n <ScreenFrame>\n <img\n ref={imageRef}\n src={src}\n alt=\"Device screen\"\n draggable={false}\n onError={handleError}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n className={`block w-full bg-black select-none ${\n onTouch ? \"cursor-pointer\" : \"\"\n }`}\n // Device screens are tiny; smoothing them turns text to mush, and a\n // hold must not start a native image drag.\n style={{ imageRendering: \"pixelated\", touchAction: \"none\" }}\n data-testid=\"image_device-screen\"\n />\n </ScreenFrame>\n );\n};\n"],
|
|
5
|
+
"mappings": "AAAA,OAAOA,GAAS,eAAAC,EAAa,aAAAC,EAAW,UAAAC,EAAQ,YAAAC,MAAgB,QAEhE,OACE,iBAAAC,EACA,gBAAAC,MACK,yCAEP,OAAS,eAAAC,MAAmB,gBAQrB,MAAMC,EAAsD,CAAC,CAClE,IAAAC,EACA,QAAAC,CACF,IAAM,CACJ,MAAMC,EAAWR,EAAyB,IAAI,EACxC,CAACS,EAAaC,CAAc,EAAIT,EAAS,EAAK,EAC9CU,EAAQR,EAAaI,CAAO,EAElCR,EAAU,IAAMW,EAAe,EAAK,EAAG,CAACJ,CAAG,CAAC,EAE5C,MAAMM,EAAqBC,GAAgD,CACzE,MAAMC,EAAQN,EAAS,QACvB,GAAI,CAACD,GAAW,CAACO,GAASD,EAAM,SAAW,EAAG,OAC9C,MAAME,EAAOD,EAAM,sBAAsB,EACnCE,EAAQd,EACZW,EAAM,QAAUE,EAAK,KACrBF,EAAM,QAAUE,EAAK,IACrBA,EACA,CAAE,MAAOD,EAAM,aAAc,OAAQA,EAAM,aAAc,CAC3D,EAGIE,GAASL,EAAM,KAAKK,CAAK,GAC3BF,EAAM,kBAAkBD,EAAM,SAAS,CAE3C,EAEMI,EAAmBJ,GAAgD,CACnEF,EAAM,QAAQ,GAChBH,EAAS,SAAS,sBAAsBK,EAAM,SAAS,CAE3D,EAEMK,EAAcpB,EAAY,IAAMY,EAAe,EAAI,EAAG,CAAC,CAAC,EAE9D,OAAID,EAEAZ,EAAA,cAAC,KACC,UAAU,gCACV,cAAY,kCACb,iCAED,EAKFA,EAAA,cAACO,EAAA,KACCP,EAAA,cAAC,OACC,IAAKW,EACL,IAAKF,EACL,IAAI,gBACJ,UAAW,GACX,QAASY,EACT,cAAeN,EACf,YAAaK,EACb,gBAAiBA,EACjB,UAAW,qCACTV,EAAU,iBAAmB,EAC/B,GAGA,MAAO,CAAE,eAAgB,YAAa,YAAa,MAAO,EAC1D,cAAY,sBACd,CACF,CAEJ",
|
|
6
|
+
"names": ["React", "useCallback", "useEffect", "useRef", "useState", "toScreenPoint", "useTouchHold", "ScreenFrame", "DeviceScreenImage", "src", "onTouch", "imageRef", "undecodable", "setUndecodable", "touch", "handlePointerDown", "event", "image", "rect", "point", "handlePointerUp", "handleError"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import s,{useMemo as t}from"react";import{MockClient as v}from"@ledgerhq/device-mockserver-client";import{mockServerScreenApi as m,useMockServerDevice as f}from"@ledgerhq/device-mockserver-react-core";import{DeviceScreen as S}from"./DeviceScreen";const D=({url:o,token:c,deviceId:e,...n})=>{const r=t(()=>new v(o,{token:c}),[o,c]),p=t(()=>m(r,e),[r,e]),i=f(r,e);return i===void 0?null:s.createElement(S,{api:p,deviceType:i?.device_type??"",firmwareVersion:i?.firmware_version,...n})};export{D as MockServerDevice};
|
|
2
|
+
//# sourceMappingURL=MockServerDevice.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/MockServerDevice.tsx"],
|
|
4
|
+
"sourcesContent": ["import React, { useMemo } from \"react\";\nimport { MockClient } from \"@ledgerhq/device-mockserver-client\";\nimport {\n mockServerScreenApi,\n useMockServerDevice,\n} from \"@ledgerhq/device-mockserver-react-core\";\n\nimport { DeviceScreen, type DeviceScreenProps } from \"./DeviceScreen\";\n\nexport type MockServerDeviceProps = Pick<\n DeviceScreenProps,\n \"floating\" | \"defaultCollapsed\"\n> & {\n url: string;\n /** Of the session owning the device: devices are scoped to their session. */\n token: string;\n deviceId: string;\n};\n\nexport const MockServerDevice: React.FC<MockServerDeviceProps> = ({\n url,\n token,\n deviceId,\n ...props\n}) => {\n const client = useMemo(() => new MockClient(url, { token }), [url, token]);\n const api = useMemo(\n () => mockServerScreenApi(client, deviceId),\n [client, deviceId],\n );\n const device = useMockServerDevice(client, deviceId);\n\n // Decides touch or buttons, so nothing renders until it is known. An\n // unreadable record still shows the screen, and its errors.\n if (device === undefined) return null;\n\n return (\n <DeviceScreen\n api={api}\n deviceType={device?.device_type ?? \"\"}\n firmwareVersion={device?.firmware_version}\n {...props}\n />\n );\n};\n"],
|
|
5
|
+
"mappings": "AAAA,OAAOA,GAAS,WAAAC,MAAe,QAC/B,OAAS,cAAAC,MAAkB,qCAC3B,OACE,uBAAAC,EACA,uBAAAC,MACK,yCAEP,OAAS,gBAAAC,MAA4C,iBAY9C,MAAMC,EAAoD,CAAC,CAChE,IAAAC,EACA,MAAAC,EACA,SAAAC,EACA,GAAGC,CACL,IAAM,CACJ,MAAMC,EAASV,EAAQ,IAAM,IAAIC,EAAWK,EAAK,CAAE,MAAAC,CAAM,CAAC,EAAG,CAACD,EAAKC,CAAK,CAAC,EACnEI,EAAMX,EACV,IAAME,EAAoBQ,EAAQF,CAAQ,EAC1C,CAACE,EAAQF,CAAQ,CACnB,EACMI,EAAST,EAAoBO,EAAQF,CAAQ,EAInD,OAAII,IAAW,OAAkB,KAG/Bb,EAAA,cAACK,EAAA,CACC,IAAKO,EACL,WAAYC,GAAQ,aAAe,GACnC,gBAAiBA,GAAQ,iBACxB,GAAGH,EACN,CAEJ",
|
|
6
|
+
"names": ["React", "useMemo", "MockClient", "mockServerScreenApi", "useMockServerDevice", "DeviceScreen", "MockServerDevice", "url", "token", "deviceId", "props", "client", "api", "device"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ScreenFrame.tsx"],
|
|
4
|
+
"sourcesContent": ["import React from \"react\";\n\ntype ScreenFrameProps = {\n children: React.ReactNode;\n};\n\n/**\n * The bezel around whatever stands in for the screen. The border lives here,\n * outside the content, so the live frame and the app list inside it take\n * exactly the screen's size.\n */\nexport const ScreenFrame: React.FC<ScreenFrameProps> = ({ children }) => (\n <div className=\"border-muted @container relative overflow-hidden rounded-md border\">\n {children}\n </div>\n);\n"],
|
|
5
|
+
"mappings": "AAAA,OAAOA,MAAW,QAWX,MAAMC,EAA0C,CAAC,CAAE,SAAAC,CAAS,IACjEF,EAAA,cAAC,OAAI,UAAU,sEACZE,CACH",
|
|
6
|
+
"names": ["React", "ScreenFrame", "children"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{findDeviceScreenModel as o}from"@ledgerhq/device-mockserver-react-core";import{Flex as n,Nano as c,NanoGen5 as r,Stax as i}from"@ledgerhq/lumen-ui-react/symbols";const t={stax:i,flex:n,apexp:r},l=e=>({...o(e),icon:t[e]??c});export{l as findDeviceScreenModel};
|
|
2
|
+
//# sourceMappingURL=deviceModels.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/deviceModels.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type DeviceScreenModel as BaseDeviceScreenModel,\n findDeviceScreenModel as findBaseDeviceScreenModel,\n} from \"@ledgerhq/device-mockserver-react-core\";\nimport { Flex, Nano, NanoGen5, Stax } from \"@ledgerhq/lumen-ui-react/symbols\";\n\nexport interface DeviceScreenModel extends BaseDeviceScreenModel {\n readonly icon: typeof Nano;\n}\n\n/** Keyed by the mock server's `device_type`; every Nano draws as one. */\nconst ICONS: Record<string, typeof Nano> = {\n stax: Stax,\n flex: Flex,\n apexp: NanoGen5,\n};\n\nexport const findDeviceScreenModel = (\n deviceType: string,\n): DeviceScreenModel => ({\n ...findBaseDeviceScreenModel(deviceType),\n icon: ICONS[deviceType] ?? Nano,\n});\n"],
|
|
5
|
+
"mappings": "AAAA,OAEE,yBAAyBA,MACpB,yCACP,OAAS,QAAAC,EAAM,QAAAC,EAAM,YAAAC,EAAU,QAAAC,MAAY,mCAO3C,MAAMC,EAAqC,CACzC,KAAMD,EACN,KAAMH,EACN,MAAOE,CACT,EAEaG,EACXC,IACuB,CACvB,GAAGP,EAA0BO,CAAU,EACvC,KAAMF,EAAME,CAAU,GAAKL,CAC7B",
|
|
6
|
+
"names": ["findBaseDeviceScreenModel", "Flex", "Nano", "NanoGen5", "Stax", "ICONS", "findDeviceScreenModel", "deviceType"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{findDeviceScreenModel as c}from"./deviceModels";import{DeviceScreen as p}from"./DeviceScreen";import{MockServerDevice as v}from"./MockServerDevice";import{mockServerScreenApi as i,useMockServerDevice as n}from"@ledgerhq/device-mockserver-react-core";export{p as DeviceScreen,v as MockServerDevice,c as findDeviceScreenModel,i as mockServerScreenApi,n as useMockServerDevice};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["export { type DeviceScreenModel, findDeviceScreenModel } from \"./deviceModels\";\nexport { DeviceScreen, type DeviceScreenProps } from \"./DeviceScreen\";\nexport {\n MockServerDevice,\n type MockServerDeviceProps,\n} from \"./MockServerDevice\";\nexport {\n type DeviceScreenState,\n type MockServerClient,\n mockServerScreenApi,\n type ScreenApi,\n useMockServerDevice,\n} from \"@ledgerhq/device-mockserver-react-core\";\n"],
|
|
5
|
+
"mappings": "AAAA,OAAiC,yBAAAA,MAA6B,iBAC9D,OAAS,gBAAAC,MAA4C,iBACrD,OACE,oBAAAC,MAEK,qBACP,OAGE,uBAAAC,EAEA,uBAAAC,MACK",
|
|
6
|
+
"names": ["findDeviceScreenModel", "DeviceScreen", "MockServerDevice", "mockServerScreenApi", "useMockServerDevice"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/webScreenPlatform.ts"],
|
|
4
|
+
"sourcesContent": ["import { type ScreenPlatform } from \"@ledgerhq/device-mockserver-react-core\";\n\nexport const webScreenPlatform: ScreenPlatform = {\n toImageSource: (screenshot) =>\n Promise.resolve(URL.createObjectURL(screenshot)),\n releaseImageSource: (source) => URL.revokeObjectURL(source),\n isHidden: () => document.hidden,\n};\n"],
|
|
5
|
+
"mappings": "AAEO,MAAMA,EAAoC,CAC/C,cAAgBC,GACd,QAAQ,QAAQ,IAAI,gBAAgBA,CAAU,CAAC,EACjD,mBAAqBC,GAAW,IAAI,gBAAgBA,CAAM,EAC1D,SAAU,IAAM,SAAS,MAC3B",
|
|
6
|
+
"names": ["webScreenPlatform", "screenshot", "source"]
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type Device } from "@ledgerhq/device-mockserver-client";
|
|
3
|
+
import { type DeviceScreenModel } from "./deviceModels";
|
|
4
|
+
type DeviceOsInfoProps = {
|
|
5
|
+
device: Device;
|
|
6
|
+
model: DeviceScreenModel;
|
|
7
|
+
/** Omitted, the apps are listed but cannot be opened. */
|
|
8
|
+
onOpenApp?: (appName: string) => Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
export declare const DeviceOsInfo: React.FC<DeviceOsInfoProps>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=DeviceOsInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceOsInfo.d.ts","sourceRoot":"","sources":["../../../src/DeviceOsInfo.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAOjE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAiCxD,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,iBAAiB,CAAC;IACzB,yDAAyD;IACzD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAwFpD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type ScreenApi } from "@ledgerhq/device-mockserver-react-core";
|
|
3
|
+
export type DeviceScreenProps = {
|
|
4
|
+
api: ScreenApi;
|
|
5
|
+
/** The mock server's `device_type`, a DMK `DeviceModelId`. */
|
|
6
|
+
deviceType: string;
|
|
7
|
+
/** Shown next to the model name in the floating window's header. */
|
|
8
|
+
firmwareVersion?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Render as a window over the page that can be dragged by its header and
|
|
11
|
+
* collapsed to it, rather than inline where it is placed.
|
|
12
|
+
*/
|
|
13
|
+
floating?: boolean;
|
|
14
|
+
defaultCollapsed?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare const DeviceScreen: React.FC<DeviceScreenProps>;
|
|
17
|
+
//# sourceMappingURL=DeviceScreen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceScreen.d.ts","sourceRoot":"","sources":["../../../src/DeviceScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAEL,KAAK,SAAS,EAEf,MAAM,wCAAwC,CAAC;AAWhD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,SAAS,CAAC;IACf,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AA4BF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAoCpD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type SpeculosAction, type SpeculosButton } from "@ledgerhq/device-mockserver-client";
|
|
3
|
+
type DeviceScreenButtonsProps = {
|
|
4
|
+
onPress: (button: SpeculosButton, action: SpeculosAction) => void;
|
|
5
|
+
};
|
|
6
|
+
export declare const DeviceScreenButtons: React.FC<DeviceScreenButtonsProps>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=DeviceScreenButtons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceScreenButtons.d.ts","sourceRoot":"","sources":["../../../src/DeviceScreenButtons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,oCAAoC,CAAC;AAW5C,KAAK,wBAAwB,GAAG;IAC9B,OAAO,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CACnE,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAsClE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type SpeculosAction } from "@ledgerhq/device-mockserver-client";
|
|
3
|
+
type DeviceScreenImageProps = {
|
|
4
|
+
src: string;
|
|
5
|
+
/** Omitted for a button-driven device. */
|
|
6
|
+
onTouch?: (x: number, y: number, action: SpeculosAction) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const DeviceScreenImage: React.FC<DeviceScreenImageProps>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=DeviceScreenImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceScreenImage.d.ts","sourceRoot":"","sources":["../../../src/DeviceScreenImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAQzE,KAAK,sBAAsB,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAClE,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAmE9D,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type DeviceScreenProps } from "./DeviceScreen";
|
|
3
|
+
export type MockServerDeviceProps = Pick<DeviceScreenProps, "floating" | "defaultCollapsed"> & {
|
|
4
|
+
url: string;
|
|
5
|
+
/** Of the session owning the device: devices are scoped to their session. */
|
|
6
|
+
token: string;
|
|
7
|
+
deviceId: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const MockServerDevice: React.FC<MockServerDeviceProps>;
|
|
10
|
+
//# sourceMappingURL=MockServerDevice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockServerDevice.d.ts","sourceRoot":"","sources":["../../../src/MockServerDevice.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAOvC,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,iBAAiB,EACjB,UAAU,GAAG,kBAAkB,CAChC,GAAG;IACF,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAyB5D,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
type ScreenFrameProps = {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* The bezel around whatever stands in for the screen. The border lives here,
|
|
7
|
+
* outside the content, so the live frame and the app list inside it take
|
|
8
|
+
* exactly the screen's size.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ScreenFrame: React.FC<ScreenFrameProps>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=ScreenFrame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenFrame.d.ts","sourceRoot":"","sources":["../../../src/ScreenFrame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAIlD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type DeviceScreenModel as BaseDeviceScreenModel } from "@ledgerhq/device-mockserver-react-core";
|
|
2
|
+
import { Nano } from "@ledgerhq/lumen-ui-react/symbols";
|
|
3
|
+
export interface DeviceScreenModel extends BaseDeviceScreenModel {
|
|
4
|
+
readonly icon: typeof Nano;
|
|
5
|
+
}
|
|
6
|
+
export declare const findDeviceScreenModel: (deviceType: string) => DeviceScreenModel;
|
|
7
|
+
//# sourceMappingURL=deviceModels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviceModels.d.ts","sourceRoot":"","sources":["../../../src/deviceModels.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,IAAI,qBAAqB,EAEhD,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAQ,IAAI,EAAkB,MAAM,kCAAkC,CAAC;AAE9E,MAAM,WAAW,iBAAkB,SAAQ,qBAAqB;IAC9D,QAAQ,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC;CAC5B;AASD,eAAO,MAAM,qBAAqB,GAChC,YAAY,MAAM,KACjB,iBAGD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { type DeviceScreenModel, findDeviceScreenModel } from "./deviceModels";
|
|
2
|
+
export { DeviceScreen, type DeviceScreenProps } from "./DeviceScreen";
|
|
3
|
+
export { MockServerDevice, type MockServerDeviceProps, } from "./MockServerDevice";
|
|
4
|
+
export { type DeviceScreenState, type MockServerClient, mockServerScreenApi, type ScreenApi, useMockServerDevice, } from "@ledgerhq/device-mockserver-react-core";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EACL,gBAAgB,EAChB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,KAAK,SAAS,EACd,mBAAmB,GACpB,MAAM,wCAAwC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webScreenPlatform.d.ts","sourceRoot":"","sources":["../../../src/webScreenPlatform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAE7E,eAAO,MAAM,iBAAiB,EAAE,cAK/B,CAAC"}
|