Simple monitor for displaying MIDI status for digital pianos.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

323 líneas
22 KiB

  1. import Keyboard, {
  2. StyledNaturalKey,
  3. StyledAccidentalKey
  4. } from '@theoryofnekomata/react-musical-keyboard'
  5. import * as React from 'react'
  6. interface ChannelData {
  7. channel: number
  8. key: number
  9. velocity: number
  10. }
  11. const RANGES = {
  12. 'C3-C5': '48|72',
  13. 'C3-C6': '48|84',
  14. 'C2-C6': '36|84',
  15. 'C2-C7': '36|96',
  16. 'E1-E7': '28|100',
  17. 'E1-G7': '28|103',
  18. 'A0-C8': '21|108',
  19. 'Full MIDI': '0|127'
  20. }
  21. const App: React.FC = () => {
  22. const [queryDeviceKey, setQueryDeviceKey] = React.useState<string>(
  23. () => new URLSearchParams(window.location.search).get('queryDeviceKey') || ''
  24. )
  25. const [range, setRange] = React.useState(
  26. () => new URLSearchParams(window.location.search).get('range') || RANGES['A0-C8']
  27. )
  28. const [scaleFactor, setScaleFactor] = React.useState<number>(() =>
  29. Number(new URLSearchParams(window.location.search).get('scaleFactor') || 1)
  30. )
  31. const [devicesLoadedTimestamp, setDevicesLoadedTimestamp] = React.useState<number>()
  32. const [midiAccess, setMidiAccess] = React.useState<MIDIAccess>()
  33. const [unaCorda, setUnaCorda] = React.useState(0)
  34. const [sostenuto, setSostenuto] = React.useState(0)
  35. const [sustain, setSustain] = React.useState(0)
  36. const [keyChannels, setKeyChannels] = React.useState<ChannelData[]>([])
  37. interface MidiMessageEvent extends Event {
  38. data: [number, number, number]
  39. }
  40. const handleChangeRange: React.ChangeEventHandler<HTMLElementTagNameMap['select']> = (e) => {
  41. const { value } = e.currentTarget
  42. setRange(value)
  43. window.electron.ipcRenderer.send('rangechange', value)
  44. }
  45. const handleChangeDevice: React.ChangeEventHandler<HTMLElementTagNameMap['select']> = (e) => {
  46. const { value } = e.currentTarget
  47. setQueryDeviceKey((oldDeviceKey) => {
  48. midiAccess?.inputs.get(oldDeviceKey)?.close()
  49. return value
  50. })
  51. if (queryDeviceKey) {
  52. window.electron.ipcRenderer.send('querydevicekeychange', value)
  53. }
  54. }
  55. const handleChangeScaleFactor: React.ChangeEventHandler<HTMLElementTagNameMap['input']> = (e) => {
  56. const { value: valueRaw } = e.currentTarget
  57. const value = Number(valueRaw)
  58. setScaleFactor(value)
  59. if (typeof value !== 'undefined') {
  60. window.electron.ipcRenderer.send('scalefactorchange', value)
  61. window.document.documentElement.style.setProperty('--size-scale-factor', value.toString())
  62. }
  63. }
  64. React.useEffect(() => {
  65. window.navigator.requestMIDIAccess().then((midiAccess) => {
  66. setMidiAccess(midiAccess)
  67. const inputDevices = Array.from(midiAccess.inputs.entries())
  68. const search = new URLSearchParams(window.location.search)
  69. const loadedQueryDeviceKey = search.get('queryDeviceKey') || inputDevices[0][0]
  70. setQueryDeviceKey(loadedQueryDeviceKey)
  71. if (loadedQueryDeviceKey) {
  72. window.electron.ipcRenderer.send('querydevicekeychange', loadedQueryDeviceKey)
  73. }
  74. setDevicesLoadedTimestamp(Date.now())
  75. })
  76. }, [])
  77. React.useEffect(() => {
  78. const search = new URLSearchParams(window.location.search)
  79. const scaleFactorRaw = search.get('scaleFactor') || '1'
  80. const scaleFactorTryNumber = Number(scaleFactorRaw)
  81. const scaleFactor = Number.isFinite(scaleFactorTryNumber) ? scaleFactorTryNumber : 1
  82. setScaleFactor(scaleFactor)
  83. }, [])
  84. React.useEffect(() => {
  85. const devices =
  86. typeof midiAccess?.inputs !== 'undefined' ? Array.from(midiAccess.inputs) : undefined
  87. if (typeof devices === 'undefined') {
  88. return
  89. }
  90. if (typeof queryDeviceKey === 'undefined') {
  91. return
  92. }
  93. const currentDeviceEntry = devices.find(([key]) => key === queryDeviceKey)
  94. if (typeof currentDeviceEntry === 'undefined') {
  95. return
  96. }
  97. const [, currentDevice] = currentDeviceEntry
  98. const listener = (e: Event): void => {
  99. if (e.type !== 'midimessage') {
  100. return
  101. }
  102. const midiEvent = e as MidiMessageEvent
  103. const [messageType, param1, param2] = midiEvent.data
  104. switch (messageType & 0b11110000) {
  105. case 0b10110000: {
  106. const controlNumber = param1
  107. const value = param2
  108. switch (controlNumber) {
  109. case 64:
  110. setSustain(value)
  111. return
  112. case 66:
  113. setSostenuto(value)
  114. return
  115. case 67:
  116. setUnaCorda(value)
  117. return
  118. default:
  119. break
  120. }
  121. return
  122. }
  123. case 0b10010000: {
  124. const channel = messageType & 0b00001111
  125. const keyNumber = param1
  126. const velocity = param2
  127. setKeyChannels((oldKeyChannels) => {
  128. if (velocity > 0) {
  129. return [
  130. ...oldKeyChannels,
  131. {
  132. channel,
  133. key: keyNumber,
  134. velocity
  135. }
  136. ]
  137. }
  138. return oldKeyChannels.filter((c) => !(c.channel === channel && c.key === keyNumber))
  139. })
  140. return
  141. }
  142. case 0b10000000: {
  143. const channel = messageType & 0b00001111
  144. const keyNumber = param1
  145. setKeyChannels((oldKeyChannels) => {
  146. return oldKeyChannels.filter((c) => !(c.channel === channel && c.key === keyNumber))
  147. })
  148. return
  149. }
  150. default:
  151. break
  152. }
  153. }
  154. currentDevice.addEventListener('midimessage', listener)
  155. return () => {
  156. currentDevice.removeEventListener('midimessage', listener)
  157. }
  158. }, [queryDeviceKey, midiAccess])
  159. const [startKeyRaw, endKeyRaw] = range.split('|')
  160. const startKey = Number(startKeyRaw)
  161. const endKey = Number(endKeyRaw)
  162. const devices =
  163. typeof midiAccess?.inputs !== 'undefined' ? Array.from(midiAccess.inputs) : undefined
  164. return (
  165. <div className="flex flex-col items-stretch justify-center h-full" key={devicesLoadedTimestamp}>
  166. <div className="flex-shrink-0 flex items-center w-full">
  167. <div className="flex-auto">
  168. <select
  169. className="w-full bg-black h-12 px-4"
  170. name="queryDeviceKey"
  171. defaultValue={queryDeviceKey}
  172. onChange={handleChangeDevice}
  173. >
  174. {devices?.map(([name, device]) => (
  175. <option key={name} value={name}>
  176. {device.name}
  177. </option>
  178. ))}
  179. </select>
  180. </div>
  181. <div className="flex-auto">
  182. <select
  183. className="w-full bg-black h-12 px-4"
  184. name="range"
  185. defaultValue={range}
  186. onChange={handleChangeRange}
  187. >
  188. {Object.entries(RANGES).map(([name, range]) => (
  189. <option key={name} value={range}>
  190. {name}
  191. </option>
  192. ))}
  193. </select>
  194. </div>
  195. <div className="flex items-center px-8 gap-8">
  196. <div>
  197. <label>
  198. <input
  199. name="scaleFactor"
  200. type="radio"
  201. value={1}
  202. defaultChecked={scaleFactor === 1}
  203. onChange={handleChangeScaleFactor}
  204. />{' '}
  205. 1x
  206. </label>
  207. </div>
  208. <div>
  209. <label>
  210. <input
  211. name="scaleFactor"
  212. type="radio"
  213. value={2}
  214. defaultChecked={scaleFactor === 2}
  215. onChange={handleChangeScaleFactor}
  216. />{' '}
  217. 2x
  218. </label>
  219. </div>
  220. </div>
  221. </div>
  222. <div className="flex-auto flex items-center h-full w-full">
  223. <div className="flex-auto h-full">
  224. <Keyboard
  225. key={range}
  226. height="100%"
  227. startKey={startKey}
  228. endKey={endKey}
  229. keyChannels={keyChannels}
  230. keyComponents={{
  231. natural: StyledNaturalKey,
  232. accidental: StyledAccidentalKey
  233. }}
  234. />
  235. </div>
  236. <div className="flex items-center gap-4 px-8">
  237. <svg
  238. style={{
  239. height: 24,
  240. width: 56,
  241. opacity: (unaCorda / 127) * 0.75 + 0.25,
  242. transition: 'opacity 125ms linear',
  243. fill: 'currentColor'
  244. }}
  245. viewBox="0 0 1145 490"
  246. xmlns="http://www.w3.org/2000/svg"
  247. >
  248. <g transform="matrix(5.55556,0,0,5.55556,-245.343,-1502.77)">
  249. <g transform="matrix(6.58103,0,0,6.58103,-3224.18,-1979.7)">
  250. <path d="M500.478,346.689L500.586,346.689C500.343,347.486 500.519,348.323 501.383,348.323C502.301,348.323 502.95,347.391 503.301,346.27L502.923,346.149C502.666,346.919 502.18,347.729 501.815,347.729C501.316,347.729 501.532,347.243 501.829,346.297L503.193,342.084L501.977,342.084L501.059,344.906C500.559,346.432 499.25,347.81 498.75,347.81C498.304,347.81 498.304,347.04 498.804,345.717L499.466,343.948C499.898,342.827 499.641,341.922 498.696,341.922C497.778,341.922 497.116,342.867 496.765,343.988L497.156,344.096C497.413,343.326 497.899,342.516 498.264,342.516C498.763,342.516 498.628,342.962 498.25,343.948L497.589,345.717C497.021,347.216 497.507,348.323 498.453,348.323C499.006,348.323 499.925,347.594 500.478,346.689ZM507.063,343.556L506.955,343.556C507.198,342.759 506.996,341.922 506.131,341.922C505.213,341.922 504.565,342.854 504.214,343.975L504.592,344.096C504.849,343.326 505.335,342.516 505.699,342.516C506.199,342.516 505.983,343.002 505.686,343.948L504.322,348.161L505.537,348.161L506.456,345.339C506.915,343.907 508.414,342.435 508.846,342.435C509.291,342.435 509.21,343.205 508.711,344.528L508.049,346.297C507.617,347.418 507.873,348.323 508.819,348.323C509.737,348.323 510.399,347.378 510.75,346.257L510.358,346.149C510.102,346.919 509.616,347.729 509.251,347.729C508.751,347.729 508.886,347.283 509.264,346.297L509.926,344.528C510.493,343.029 510.088,341.922 509.143,341.922C508.589,341.922 507.684,342.638 507.063,343.556ZM514.836,347.094L514.931,347.094C514.931,347.837 515.174,348.269 515.836,348.269C516.727,348.269 517.389,347.324 517.74,346.243L517.375,346.135C517.119,346.905 516.633,347.675 516.268,347.675C516.052,347.675 515.971,347.58 515.971,347.405C515.971,347.175 516.106,346.784 516.281,346.243L517.632,342.084L516.416,342.084L516.133,342.975L516.025,342.975C515.903,342.327 515.579,341.922 514.904,341.922C513.689,341.922 512.298,343.178 511.798,344.758C511.663,345.177 511.595,345.676 511.595,346.162C511.595,347.27 511.974,348.323 512.973,348.323C513.621,348.323 514.323,347.81 514.836,347.094ZM515.066,342.435C515.566,342.435 515.728,342.881 515.728,343.462C515.728,343.907 515.633,344.434 515.498,344.893L515.35,345.352C514.958,346.446 514.134,347.715 513.175,347.715C512.838,347.715 512.703,347.418 512.703,346.973C512.703,346.432 512.892,345.676 513.135,344.92C513.473,343.934 514.134,342.435 515.066,342.435ZM500.046,349.314C500.559,349.314 500.762,349.705 500.505,349.921C500.168,350.205 500.019,350.489 500.019,350.84C500.019,351.245 500.316,351.542 500.681,351.542C501.181,351.542 501.559,351.002 501.559,350.448C501.559,349.8 500.992,348.922 499.992,348.922C498.399,348.922 496.63,350.826 496.63,352.973C496.63,354.229 497.291,355.323 498.588,355.323C499.587,355.323 500.532,354.634 501.073,353.419L500.667,353.297C500.019,354.405 499.385,354.81 498.736,354.81C497.683,354.81 497.724,353.608 498.237,351.961C498.601,350.813 499.087,349.314 500.046,349.314ZM506.55,350.205C506.55,350.813 506.28,351.609 506.05,352.298C505.686,353.446 505.213,354.918 504.254,354.918C503.674,354.918 503.458,354.526 503.458,354.027C503.458,353.432 503.728,352.649 503.944,351.961C504.322,350.813 504.795,349.287 505.753,349.287C506.334,349.287 506.55,349.692 506.55,350.205ZM505.699,348.922C504.106,348.922 502.337,350.826 502.337,352.973C502.337,354.229 502.998,355.323 504.295,355.323C505.605,355.323 506.942,354.067 507.455,352.514C507.59,352.096 507.657,351.677 507.657,351.272C507.657,350.016 506.996,348.922 505.699,348.922ZM511.622,350.178L511.528,350.178C511.474,349.53 511.298,348.922 510.556,348.922C509.489,348.922 508.827,350.124 508.3,351.825L508.692,351.92C509.165,350.516 509.745,349.516 510.164,349.516C510.704,349.516 510.34,351.042 510.15,351.636L509.003,355.161L510.218,355.161L511.244,352.015C511.541,351.096 511.852,350.313 512.419,349.854C512.649,349.665 512.824,349.746 512.865,350.124C512.905,350.529 513.189,350.745 513.527,350.745C513.986,350.745 514.283,350.313 514.283,349.813C514.283,349.3 513.851,348.909 513.337,348.909C512.824,348.909 512.163,349.422 511.622,350.178ZM517.789,354.094C517.789,354.729 518.194,355.269 518.963,355.269C519.774,355.269 520.746,354.526 521.259,352.892L520.827,352.784C520.354,354.189 519.558,354.675 519.22,354.675C518.977,354.675 518.869,354.567 518.869,354.324C518.869,354.094 518.977,353.73 519.139,353.243L521.475,346.059L518.896,346.221L518.774,346.64L519.274,346.64C519.625,346.64 519.868,346.856 519.868,347.167C519.868,347.234 519.855,347.302 519.828,347.383L518.99,349.975L518.882,349.975C518.761,349.327 518.437,348.922 517.762,348.922C516.546,348.922 515.155,350.178 514.656,351.758C514.521,352.177 514.453,352.69 514.453,353.176C514.453,354.283 514.831,355.323 515.831,355.323C516.479,355.323 517.181,354.81 517.694,354.094L517.789,354.094ZM517.924,349.435C518.423,349.435 518.585,349.894 518.585,350.475C518.585,350.921 518.491,351.447 518.356,351.906L518.221,352.352C517.816,353.432 516.992,354.715 516.033,354.715C515.695,354.715 515.56,354.418 515.56,353.973C515.56,353.432 515.749,352.676 515.993,351.92C516.33,350.934 516.992,349.435 517.924,349.435ZM525.022,354.094L525.116,354.094C525.116,354.837 525.359,355.269 526.021,355.269C526.912,355.269 527.574,354.324 527.925,353.243L527.56,353.135C527.304,353.905 526.818,354.675 526.453,354.675C526.237,354.675 526.156,354.58 526.156,354.405C526.156,354.175 526.291,353.784 526.467,353.243L527.817,349.084L526.602,349.084L526.318,349.975L526.21,349.975C526.088,349.327 525.764,348.922 525.089,348.922C523.874,348.922 522.483,350.178 521.983,351.758C521.848,352.177 521.781,352.676 521.781,353.162C521.781,354.27 522.159,355.323 523.158,355.323C523.806,355.323 524.508,354.81 525.022,354.094ZM525.251,349.435C525.751,349.435 525.913,349.881 525.913,350.462C525.913,350.907 525.818,351.434 525.683,351.893L525.535,352.352C525.143,353.446 524.319,354.715 523.361,354.715C523.023,354.715 522.888,354.418 522.888,353.973C522.888,353.432 523.077,352.676 523.32,351.92C523.658,350.934 524.319,349.435 525.251,349.435Z" />
  251. </g>
  252. </g>
  253. </svg>
  254. <svg
  255. style={{
  256. height: 24,
  257. width: 44,
  258. opacity: (sostenuto / 127) * 0.75 + 0.25,
  259. transition: 'opacity 125ms linear',
  260. fill: 'currentColor'
  261. }}
  262. viewBox="0 0 975 534"
  263. xmlns="http://www.w3.org/2000/svg"
  264. >
  265. <g transform="matrix(5.55556,0,0,5.55556,-1586.71,-1466.67)">
  266. <g transform="matrix(6.58103,0,0,6.58103,-3224.18,-1979.7)">
  267. <g transform="matrix(24.0716,0,0,24.0716,533.318,355.161)">
  268. <path d="M0.474,-0.039C0.486,-0.02 0.511,0.01 0.534,0.01C0.577,0.01 0.627,-0.089 0.639,-0.127C0.643,-0.14 0.668,-0.205 0.672,-0.205C0.675,-0.205 0.674,-0.197 0.682,-0.183C0.687,-0.174 0.696,-0.163 0.702,-0.156C0.706,-0.151 0.707,-0.15 0.707,-0.148C0.707,-0.146 0.706,-0.145 0.702,-0.139C0.666,-0.087 0.662,-0.074 0.662,-0.061C0.662,-0.023 0.698,0.01 0.727,0.01C0.767,0.01 0.82,-0.049 0.82,-0.109C0.82,-0.143 0.8,-0.17 0.769,-0.197L0.765,-0.2C0.74,-0.222 0.72,-0.241 0.72,-0.251C0.72,-0.264 0.729,-0.276 0.738,-0.276C0.748,-0.276 0.757,-0.272 0.765,-0.269C0.776,-0.265 0.784,-0.263 0.791,-0.263C0.8,-0.263 0.805,-0.269 0.805,-0.281C0.805,-0.299 0.792,-0.295 0.777,-0.304C0.767,-0.31 0.762,-0.32 0.762,-0.335C0.762,-0.366 0.792,-0.383 0.828,-0.383C0.866,-0.383 0.88,-0.367 0.88,-0.333C0.88,-0.294 0.877,-0.294 0.869,-0.294L0.845,-0.294C0.834,-0.294 0.828,-0.288 0.828,-0.277C0.828,-0.266 0.834,-0.26 0.845,-0.26L0.867,-0.26C0.873,-0.26 0.875,-0.26 0.875,-0.253L0.875,-0.247C0.87,-0.184 0.868,-0.147 0.868,-0.092C0.868,-0.042 0.876,0.008 0.924,0.008C0.983,0.008 1.002,-0.077 1.002,-0.124C1.002,-0.136 0.996,-0.139 0.989,-0.139C0.979,-0.139 0.976,-0.131 0.975,-0.123C0.969,-0.08 0.961,-0.053 0.948,-0.053C0.938,-0.053 0.935,-0.065 0.935,-0.104C0.935,-0.139 0.938,-0.183 0.941,-0.243C0.942,-0.26 0.943,-0.26 0.951,-0.26L0.997,-0.26C1.008,-0.26 1.014,-0.266 1.014,-0.277C1.014,-0.288 1.008,-0.294 0.997,-0.294L0.95,-0.294C0.945,-0.294 0.944,-0.295 0.944,-0.301C0.944,-0.307 0.945,-0.317 0.945,-0.333C0.945,-0.388 0.913,-0.414 0.84,-0.414C0.775,-0.414 0.736,-0.38 0.736,-0.335C0.736,-0.312 0.749,-0.307 0.749,-0.303C0.749,-0.302 0.74,-0.301 0.736,-0.301C0.697,-0.301 0.672,-0.262 0.656,-0.232C0.649,-0.219 0.647,-0.211 0.643,-0.211C0.639,-0.211 0.638,-0.222 0.628,-0.239C0.614,-0.263 0.581,-0.305 0.553,-0.305C0.535,-0.305 0.517,-0.295 0.494,-0.266C0.455,-0.216 0.444,-0.168 0.444,-0.128C0.444,-0.089 0.461,-0.06 0.474,-0.039ZM0.012,0.015C0.023,0.015 0.025,0.009 0.028,0C0.04,-0.037 0.059,-0.081 0.084,-0.081C0.095,-0.081 0.106,-0.073 0.121,-0.062L0.13,-0.055C0.163,-0.03 0.217,0.01 0.262,0.01C0.321,0.01 0.419,-0.059 0.419,-0.21C0.419,-0.322 0.362,-0.361 0.302,-0.361C0.219,-0.361 0.163,-0.32 0.112,-0.32C0.087,-0.32 0.061,-0.346 0.061,-0.395C0.061,-0.447 0.101,-0.479 0.141,-0.479C0.199,-0.479 0.217,-0.423 0.302,-0.423C0.355,-0.423 0.391,-0.466 0.391,-0.524C0.391,-0.567 0.366,-0.591 0.324,-0.591C0.312,-0.591 0.275,-0.59 0.275,-0.572C0.275,-0.565 0.28,-0.561 0.285,-0.561C0.293,-0.561 0.304,-0.565 0.323,-0.565C0.351,-0.565 0.363,-0.549 0.363,-0.53C0.363,-0.515 0.358,-0.508 0.341,-0.508C0.285,-0.508 0.252,-0.55 0.195,-0.55C0.111,-0.55 0.024,-0.489 0.024,-0.367C0.024,-0.28 0.074,-0.226 0.134,-0.226C0.224,-0.226 0.279,-0.271 0.318,-0.271C0.348,-0.271 0.381,-0.23 0.381,-0.177C0.381,-0.131 0.364,-0.087 0.328,-0.087C0.298,-0.087 0.265,-0.093 0.226,-0.115C0.176,-0.143 0.154,-0.167 0.119,-0.167C0.051,-0.167 0.014,-0.078 0.003,-0.022C0.001,-0.012 0,-0.003 0,0.001C0,0.008 0.002,0.015 0.012,0.015ZM0.536,-0.241C0.549,-0.241 0.565,-0.218 0.572,-0.205C0.58,-0.19 0.593,-0.165 0.593,-0.13C0.593,-0.101 0.575,-0.063 0.553,-0.063C0.521,-0.063 0.494,-0.149 0.494,-0.176C0.494,-0.2 0.511,-0.241 0.536,-0.241ZM1.021,-0.035C1.021,-0.01 1.039,0.008 1.064,0.008C1.089,0.008 1.107,-0.01 1.107,-0.035C1.107,-0.06 1.089,-0.078 1.064,-0.078C1.039,-0.078 1.021,-0.06 1.021,-0.035ZM0.726,-0.129C0.728,-0.129 0.73,-0.127 0.736,-0.12L0.742,-0.114C0.764,-0.09 0.776,-0.077 0.776,-0.065C0.776,-0.056 0.769,-0.044 0.758,-0.044C0.731,-0.044 0.703,-0.069 0.703,-0.084C0.703,-0.092 0.719,-0.129 0.726,-0.129Z" />
  269. </g>
  270. </g>
  271. </g>
  272. </svg>
  273. <svg
  274. style={{
  275. height: 24,
  276. width: 43,
  277. opacity: (sustain / 127) * 0.75 + 0.25,
  278. fill: 'currentColor'
  279. }}
  280. viewBox="0 0 897 496"
  281. xmlns="http://www.w3.org/2000/svg"
  282. >
  283. <g transform="matrix(5.55556,0,0,5.55556,-2803.19,-1498.35)">
  284. <g transform="matrix(6.58103,0,0,6.58103,-3224.18,-1979.7)">
  285. <g transform="matrix(24.0716,0,0,24.0716,566.59,355.161)">
  286. <path d="M0.085,-0.261C0.131,-0.261 0.167,-0.314 0.167,-0.375C0.167,-0.402 0.162,-0.407 0.156,-0.407C0.148,-0.407 0.147,-0.398 0.142,-0.381C0.138,-0.366 0.126,-0.333 0.096,-0.333C0.067,-0.333 0.059,-0.359 0.059,-0.381L0.059,-0.385C0.062,-0.479 0.16,-0.529 0.245,-0.529C0.253,-0.529 0.259,-0.528 0.259,-0.522C0.259,-0.514 0.25,-0.502 0.244,-0.492C0.229,-0.469 0.19,-0.406 0.19,-0.379C0.19,-0.353 0.231,-0.308 0.245,-0.289C0.258,-0.271 0.286,-0.244 0.286,-0.211C0.286,-0.191 0.28,-0.178 0.265,-0.158C0.252,-0.14 0.251,-0.139 0.232,-0.132C0.188,-0.116 0.102,-0.061 0.102,-0.02C0.102,-0.003 0.119,0.008 0.136,0.008C0.166,0.008 0.194,-0.023 0.238,-0.075L0.252,-0.092C0.257,-0.098 0.261,-0.104 0.269,-0.104C0.309,-0.104 0.324,0.003 0.377,0.003C0.394,0.003 0.407,0 0.438,-0.029L0.464,-0.054C0.468,-0.058 0.472,-0.062 0.476,-0.062C0.478,-0.062 0.479,-0.06 0.483,-0.052C0.498,-0.02 0.523,0.006 0.562,0.006C0.593,0.006 0.621,-0.009 0.657,-0.046C0.674,-0.064 0.681,-0.074 0.686,-0.074C0.69,-0.074 0.692,-0.069 0.696,-0.062C0.715,-0.025 0.748,0.003 0.8,0.003C0.86,0.003 0.923,-0.057 0.923,-0.172C0.923,-0.386 0.727,-0.462 0.55,-0.498C0.545,-0.499 0.538,-0.5 0.532,-0.5C0.522,-0.5 0.519,-0.494 0.519,-0.488C0.519,-0.481 0.525,-0.476 0.542,-0.472C0.714,-0.431 0.849,-0.35 0.849,-0.154C0.849,-0.085 0.837,-0.027 0.8,-0.027C0.767,-0.027 0.745,-0.092 0.745,-0.159C0.745,-0.218 0.754,-0.262 0.786,-0.294C0.792,-0.3 0.793,-0.303 0.793,-0.307C0.793,-0.313 0.789,-0.318 0.782,-0.318C0.777,-0.318 0.77,-0.316 0.759,-0.31C0.71,-0.283 0.677,-0.234 0.677,-0.15L0.677,-0.132C0.677,-0.111 0.675,-0.104 0.655,-0.084C0.624,-0.053 0.609,-0.048 0.592,-0.048C0.567,-0.048 0.546,-0.081 0.539,-0.103C0.538,-0.107 0.537,-0.11 0.537,-0.113C0.537,-0.116 0.539,-0.118 0.546,-0.123L0.556,-0.13C0.602,-0.163 0.651,-0.197 0.651,-0.254C0.651,-0.293 0.625,-0.315 0.586,-0.315C0.494,-0.315 0.462,-0.23 0.462,-0.151C0.462,-0.137 0.463,-0.122 0.466,-0.106L0.466,-0.102C0.466,-0.099 0.465,-0.097 0.46,-0.093C0.444,-0.082 0.434,-0.077 0.42,-0.077C0.397,-0.077 0.379,-0.094 0.362,-0.111C0.345,-0.128 0.329,-0.137 0.313,-0.141C0.302,-0.144 0.296,-0.143 0.296,-0.147C0.296,-0.15 0.298,-0.153 0.303,-0.16C0.322,-0.187 0.354,-0.236 0.354,-0.27C0.354,-0.302 0.333,-0.321 0.298,-0.362C0.269,-0.396 0.256,-0.416 0.256,-0.437C0.256,-0.45 0.267,-0.48 0.279,-0.5C0.295,-0.527 0.31,-0.53 0.321,-0.53C0.375,-0.53 0.424,-0.489 0.424,-0.433C0.424,-0.411 0.41,-0.399 0.392,-0.399C0.375,-0.399 0.361,-0.404 0.348,-0.418C0.342,-0.424 0.338,-0.432 0.329,-0.432C0.323,-0.432 0.319,-0.427 0.319,-0.419C0.319,-0.396 0.354,-0.327 0.419,-0.327C0.465,-0.327 0.494,-0.364 0.494,-0.408C0.494,-0.515 0.385,-0.555 0.293,-0.555L0.287,-0.555C0.227,-0.554 0.181,-0.548 0.124,-0.52C0.074,-0.495 0,-0.439 0,-0.359C0,-0.315 0.026,-0.261 0.085,-0.261ZM0.976,0C1.001,0 1.019,-0.018 1.019,-0.043C1.019,-0.068 1.001,-0.086 0.976,-0.086C0.951,-0.086 0.933,-0.068 0.933,-0.043C0.933,-0.018 0.951,0 0.976,0ZM0.525,-0.196C0.525,-0.24 0.536,-0.28 0.566,-0.28C0.582,-0.28 0.589,-0.266 0.589,-0.238C0.589,-0.205 0.572,-0.181 0.542,-0.157C0.537,-0.153 0.533,-0.151 0.531,-0.151C0.529,-0.151 0.527,-0.153 0.527,-0.158C0.526,-0.17 0.525,-0.182 0.525,-0.196Z" />
  287. </g>
  288. </g>
  289. </g>
  290. </svg>
  291. </div>
  292. </div>
  293. </div>
  294. )
  295. }
  296. export default App