完善虚拟机连接
							
								
								
									
										2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,3 +1,3 @@
 | 
			
		||||
[submodule "novnc"]
 | 
			
		||||
	path = novnc
 | 
			
		||||
	path = VM/novnc
 | 
			
		||||
	url = https://github.com/novnc/noVNC
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						@ -136,8 +136,8 @@ copy-files:
 | 
			
		||||
	cp -rv InstallBox86.sh  deb/opt/apps/deepin-wine-runner
 | 
			
		||||
	cp -rv InstallRuntime   deb/opt/apps/deepin-wine-runner
 | 
			
		||||
	cp -rv globalenv.py   deb/opt/apps/deepin-wine-runner
 | 
			
		||||
	if [[ ! -d novnc/utils/websockify ]]; then git submodule update --init --recursive ; fi
 | 
			
		||||
	if [[ ! -d novnc/utils/websockify ]]; then cd novnc/utils; git clone https://github.com/novnc/websockify ; fi
 | 
			
		||||
	if [[ ! -d VM/novnc/utils/websockify ]]; then git submodule update --init --recursive ; fi
 | 
			
		||||
	if [[ ! -d VM/novnc/utils/websockify ]]; then cd VM/novnc/utils; git clone https://github.com/novnc/websockify ; fi
 | 
			
		||||
	cp -rv novnc   deb/opt/apps/deepin-wine-runner
 | 
			
		||||
	mkdir -pv deb/opt/apps/deepin-wine-runner/entries/
 | 
			
		||||
	cp -rv deb/usr/share/applications deb/opt/apps/deepin-wine-runner/entries/applications
 | 
			
		||||
 | 
			
		||||
@ -327,4 +327,5 @@ ui.action_StopVirtualBox.triggered.connect(on_action_StopVirtualBox_triggered)
 | 
			
		||||
ui.actionQemuDiskAddSpace.triggered.connect(on_actionQemuDiskAddSpace_triggered)
 | 
			
		||||
ui.getDCLC.triggered.connect(on_getDCLC_triggered)
 | 
			
		||||
window.show()
 | 
			
		||||
sys.exit(app.exec_())
 | 
			
		||||
if (__name__ == "__main__"):
 | 
			
		||||
    sys.exit(app.exec_())
 | 
			
		||||
							
								
								
									
										34
									
								
								VM/novnc/.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
			
		||||
---
 | 
			
		||||
name: Bug report
 | 
			
		||||
about: Create a report to help us improve
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
**Describe the bug**
 | 
			
		||||
A clear and concise description of what the bug is.
 | 
			
		||||
 | 
			
		||||
**To Reproduce**
 | 
			
		||||
Steps to reproduce the behavior:
 | 
			
		||||
1. Go to '...'
 | 
			
		||||
2. Click on '....'
 | 
			
		||||
3. Scroll down to '....'
 | 
			
		||||
4. See error
 | 
			
		||||
 | 
			
		||||
**Expected behavior**
 | 
			
		||||
A clear and concise description of what you expected to happen.
 | 
			
		||||
 | 
			
		||||
**Screenshots**
 | 
			
		||||
If applicable, add screenshots to help explain your problem.
 | 
			
		||||
 | 
			
		||||
**Client (please complete the following information):**
 | 
			
		||||
 - OS: [e.g. iOS]
 | 
			
		||||
 - Browser: [e.g. chrome, safari]
 | 
			
		||||
 - Browser version: [e.g. 22]
 | 
			
		||||
 | 
			
		||||
**Server (please complete the following information):**
 | 
			
		||||
 - noVNC version: [e.g. 1.0.0 or git commit id]
 | 
			
		||||
 - VNC server: [e.g. QEMU, TigerVNC]
 | 
			
		||||
 - WebSocket proxy: [e.g. websockify]
 | 
			
		||||
 | 
			
		||||
**Additional context**
 | 
			
		||||
Add any other context about the problem here.
 | 
			
		||||
							
								
								
									
										5
									
								
								VM/novnc/.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,5 @@
 | 
			
		||||
blank_issues_enabled: false
 | 
			
		||||
contact_links:
 | 
			
		||||
  - name: Question or discussion
 | 
			
		||||
    url: https://groups.google.com/forum/?fromgroups#!forum/novnc
 | 
			
		||||
    about: Ask a question or start a discussion
 | 
			
		||||
							
								
								
									
										17
									
								
								VM/novnc/.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,17 @@
 | 
			
		||||
---
 | 
			
		||||
name: Feature request
 | 
			
		||||
about: Suggest an idea for this project
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
**Is your feature request related to a problem? Please describe.**
 | 
			
		||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
 | 
			
		||||
 | 
			
		||||
**Describe the solution you'd like**
 | 
			
		||||
A clear and concise description of what you want to happen.
 | 
			
		||||
 | 
			
		||||
**Describe alternatives you've considered**
 | 
			
		||||
A clear and concise description of any alternative solutions or features you've considered.
 | 
			
		||||
 | 
			
		||||
**Additional context**
 | 
			
		||||
Add any other context or screenshots about the feature request here.
 | 
			
		||||
							
								
								
									
										97
									
								
								VM/novnc/.github/workflows/deploy.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,97 @@
 | 
			
		||||
name: Publish
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
  pull_request:
 | 
			
		||||
  release:
 | 
			
		||||
    types: [published]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  npm:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - run: |
 | 
			
		||||
          GITREV=$(git rev-parse --short HEAD)
 | 
			
		||||
          echo $GITREV
 | 
			
		||||
          sed -i "s/^\(.*\"version\".*\)\"\([^\"]\+\)\"\(.*\)\$/\1\"\2-g$GITREV\"\3/" package.json
 | 
			
		||||
        if: github.event_name != 'release'
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
        with:
 | 
			
		||||
          # Needs to be explicitly specified for auth to work
 | 
			
		||||
          registry-url: 'https://registry.npmjs.org'
 | 
			
		||||
      - run: npm install
 | 
			
		||||
      - uses: actions/upload-artifact@v4
 | 
			
		||||
        with:
 | 
			
		||||
          name: npm
 | 
			
		||||
          path: lib
 | 
			
		||||
      - run: npm publish --access public
 | 
			
		||||
        env:
 | 
			
		||||
          NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
 | 
			
		||||
        if: |
 | 
			
		||||
          github.repository == 'novnc/noVNC' &&
 | 
			
		||||
          github.event_name == 'release' &&
 | 
			
		||||
          !github.event.release.prerelease
 | 
			
		||||
      - run: npm publish --access public --tag beta
 | 
			
		||||
        env:
 | 
			
		||||
          NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
 | 
			
		||||
        if: |
 | 
			
		||||
          github.repository == 'novnc/noVNC' &&
 | 
			
		||||
          github.event_name == 'release' &&
 | 
			
		||||
          github.event.release.prerelease
 | 
			
		||||
      - run: npm publish --access public --tag dev
 | 
			
		||||
        env:
 | 
			
		||||
          NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
 | 
			
		||||
        if: |
 | 
			
		||||
          github.repository == 'novnc/noVNC' &&
 | 
			
		||||
          github.event_name == 'push' &&
 | 
			
		||||
          github.event.ref == 'refs/heads/master'
 | 
			
		||||
  snap:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - run: |
 | 
			
		||||
          GITREV=$(git rev-parse --short HEAD)
 | 
			
		||||
          echo $GITREV
 | 
			
		||||
          sed -i "s/^\(.*\"version\".*\)\"\([^\"]\+\)\"\(.*\)\$/\1\"\2-g$GITREV\"\3/" package.json
 | 
			
		||||
        if: github.event_name != 'release'
 | 
			
		||||
      - run: |
 | 
			
		||||
          VERSION=$(grep '"version"' package.json | cut -d '"' -f 4)
 | 
			
		||||
          echo $VERSION
 | 
			
		||||
          sed -i "s/^version:.*/version: '$VERSION'/" snap/snapcraft.yaml
 | 
			
		||||
      - uses: snapcore/action-build@v1
 | 
			
		||||
        id: snapcraft
 | 
			
		||||
      - uses: actions/upload-artifact@v4
 | 
			
		||||
        with:
 | 
			
		||||
          name: snap
 | 
			
		||||
          path: ${{ steps.snapcraft.outputs.snap }}
 | 
			
		||||
      - uses: snapcore/action-publish@v1
 | 
			
		||||
        with:
 | 
			
		||||
          snap: ${{ steps.snapcraft.outputs.snap }}
 | 
			
		||||
          release: stable
 | 
			
		||||
        env:
 | 
			
		||||
          SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_LOGIN }}
 | 
			
		||||
        if: |
 | 
			
		||||
          github.repository == 'novnc/noVNC' &&
 | 
			
		||||
          github.event_name == 'release' &&
 | 
			
		||||
          !github.event.release.prerelease
 | 
			
		||||
      - uses: snapcore/action-publish@v1
 | 
			
		||||
        with:
 | 
			
		||||
          snap: ${{ steps.snapcraft.outputs.snap }}
 | 
			
		||||
          release: beta
 | 
			
		||||
        env:
 | 
			
		||||
          SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_LOGIN }}
 | 
			
		||||
        if: |
 | 
			
		||||
          github.repository == 'novnc/noVNC' &&
 | 
			
		||||
          github.event_name == 'release' &&
 | 
			
		||||
          github.event.release.prerelease
 | 
			
		||||
      - uses: snapcore/action-publish@v1
 | 
			
		||||
        with:
 | 
			
		||||
          snap: ${{ steps.snapcraft.outputs.snap }}
 | 
			
		||||
          release: edge
 | 
			
		||||
        env:
 | 
			
		||||
          SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_LOGIN }}
 | 
			
		||||
        if: |
 | 
			
		||||
          github.repository == 'novnc/noVNC' &&
 | 
			
		||||
          github.event_name == 'push' &&
 | 
			
		||||
          github.event.ref == 'refs/heads/master'
 | 
			
		||||
							
								
								
									
										19
									
								
								VM/novnc/.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,19 @@
 | 
			
		||||
name: Lint
 | 
			
		||||
 | 
			
		||||
on: [push, pull_request]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  eslint:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
      - run: npm update
 | 
			
		||||
      - run: npm run lint
 | 
			
		||||
  html:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
      - run: npm update
 | 
			
		||||
      - run: git ls-tree --name-only -r HEAD | grep -E "[.](html|css)$" | xargs ./utils/validate
 | 
			
		||||
							
								
								
									
										28
									
								
								VM/novnc/.github/workflows/test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,28 @@
 | 
			
		||||
name: Test
 | 
			
		||||
 | 
			
		||||
on: [push, pull_request]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  test:
 | 
			
		||||
    strategy:
 | 
			
		||||
      matrix:
 | 
			
		||||
        os:
 | 
			
		||||
          - ubuntu-latest
 | 
			
		||||
          - windows-latest
 | 
			
		||||
        browser:
 | 
			
		||||
          - ChromeHeadless
 | 
			
		||||
          - FirefoxHeadless
 | 
			
		||||
        include:
 | 
			
		||||
          - os: macos-latest
 | 
			
		||||
            browser: Safari
 | 
			
		||||
          - os: windows-latest
 | 
			
		||||
            browser: EdgeHeadless
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
    runs-on: ${{ matrix.os }}
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
      - run: npm update
 | 
			
		||||
      - run: npm run test
 | 
			
		||||
        env:
 | 
			
		||||
          TEST_BROWSER_NAME: ${{ matrix.browser }}
 | 
			
		||||
							
								
								
									
										15
									
								
								VM/novnc/.github/workflows/translate.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,15 @@
 | 
			
		||||
name: Translate
 | 
			
		||||
 | 
			
		||||
on: [push, pull_request]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  translate:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v4
 | 
			
		||||
      - uses: actions/setup-node@v4
 | 
			
		||||
      - run: npm update
 | 
			
		||||
      - run: sudo apt-get install gettext
 | 
			
		||||
      - run: make -C po update-pot
 | 
			
		||||
      - run: make -C po update-po
 | 
			
		||||
      - run: make -C po update-js
 | 
			
		||||
							
								
								
									
										12
									
								
								VM/novnc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,12 @@
 | 
			
		||||
*.pyc
 | 
			
		||||
*.o
 | 
			
		||||
tests/data_*.js
 | 
			
		||||
utils/rebind.so
 | 
			
		||||
utils/websockify
 | 
			
		||||
/node_modules
 | 
			
		||||
/build
 | 
			
		||||
/lib
 | 
			
		||||
recordings
 | 
			
		||||
*.swp
 | 
			
		||||
*~
 | 
			
		||||
noVNC-*.tgz
 | 
			
		||||
							
								
								
									
										0
									
								
								VM/novnc/.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										13
									
								
								VM/novnc/AUTHORS
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,13 @@
 | 
			
		||||
maintainers:
 | 
			
		||||
- Samuel Mannehed for Cendio AB (@samhed)
 | 
			
		||||
- Pierre Ossman for Cendio AB (@CendioOssman)
 | 
			
		||||
maintainersEmeritus:
 | 
			
		||||
- Joel Martin (@kanaka)
 | 
			
		||||
- Solly Ross (@directxman12)
 | 
			
		||||
- @astrand 
 | 
			
		||||
contributors:
 | 
			
		||||
# There are a bunch of people that should be here.
 | 
			
		||||
# If you want to be on this list, feel free send a PR
 | 
			
		||||
# to add yourself.
 | 
			
		||||
- jalf <git@jalf.dk>
 | 
			
		||||
- NTT corp.
 | 
			
		||||
							
								
								
									
										62
									
								
								VM/novnc/LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,62 @@
 | 
			
		||||
noVNC is Copyright (C) 2022 The noVNC Authors
 | 
			
		||||
(./AUTHORS)
 | 
			
		||||
 | 
			
		||||
The noVNC core library files are licensed under the MPL 2.0 (Mozilla
 | 
			
		||||
Public License 2.0). The noVNC core library is composed of the
 | 
			
		||||
Javascript code necessary for full noVNC operation. This includes (but
 | 
			
		||||
is not limited to):
 | 
			
		||||
 | 
			
		||||
    core/**/*.js
 | 
			
		||||
    app/*.js
 | 
			
		||||
    test/playback.js
 | 
			
		||||
 | 
			
		||||
The HTML, CSS, font and images files that included with the noVNC
 | 
			
		||||
source distibution (or repository) are not considered part of the
 | 
			
		||||
noVNC core library and are licensed under more permissive licenses.
 | 
			
		||||
The intent is to allow easy integration of noVNC into existing web
 | 
			
		||||
sites and web applications.
 | 
			
		||||
 | 
			
		||||
The HTML, CSS, font and image files are licensed as follows:
 | 
			
		||||
 | 
			
		||||
    *.html                     : 2-Clause BSD license
 | 
			
		||||
 | 
			
		||||
    app/styles/*.css           : 2-Clause BSD license
 | 
			
		||||
 | 
			
		||||
    app/styles/Orbitron*       : SIL Open Font License 1.1
 | 
			
		||||
                                 (Copyright 2009 Matt McInerney)
 | 
			
		||||
 | 
			
		||||
    app/images/                : Creative Commons Attribution-ShareAlike
 | 
			
		||||
                                 http://creativecommons.org/licenses/by-sa/3.0/
 | 
			
		||||
 | 
			
		||||
Some portions of noVNC are copyright to their individual authors.
 | 
			
		||||
Please refer to the individual source files and/or to the noVNC commit
 | 
			
		||||
history: https://github.com/novnc/noVNC/commits/master
 | 
			
		||||
 | 
			
		||||
The are several files and projects that have been incorporated into
 | 
			
		||||
the noVNC core library. Here is a list of those files and the original
 | 
			
		||||
licenses (all MPL 2.0 compatible):
 | 
			
		||||
 | 
			
		||||
    core/base64.js          : MPL 2.0
 | 
			
		||||
 | 
			
		||||
    core/des.js             : Various BSD style licenses
 | 
			
		||||
 | 
			
		||||
    vendor/pako/            : MIT
 | 
			
		||||
 | 
			
		||||
Any other files not mentioned above are typically marked with
 | 
			
		||||
a copyright/license header at the top of the file. The default noVNC
 | 
			
		||||
license is MPL-2.0.
 | 
			
		||||
 | 
			
		||||
The following license texts are included:
 | 
			
		||||
 | 
			
		||||
    docs/LICENSE.MPL-2.0
 | 
			
		||||
    docs/LICENSE.OFL-1.1
 | 
			
		||||
    docs/LICENSE.BSD-3-Clause (New BSD)
 | 
			
		||||
    docs/LICENSE.BSD-2-Clause (Simplified BSD / FreeBSD)
 | 
			
		||||
    vendor/pako/LICENSE (MIT)
 | 
			
		||||
 | 
			
		||||
Or alternatively the license texts may be found here:
 | 
			
		||||
 | 
			
		||||
    http://www.mozilla.org/MPL/2.0/
 | 
			
		||||
    http://scripts.sil.org/OFL
 | 
			
		||||
    http://en.wikipedia.org/wiki/BSD_licenses
 | 
			
		||||
    https://opensource.org/licenses/MIT
 | 
			
		||||
							
								
								
									
										227
									
								
								VM/novnc/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,227 @@
 | 
			
		||||
## noVNC: HTML VNC Client Library and Application
 | 
			
		||||
 | 
			
		||||
[](https://github.com/novnc/noVNC/actions?query=workflow%3ATest)
 | 
			
		||||
[](https://github.com/novnc/noVNC/actions?query=workflow%3ALint)
 | 
			
		||||
 | 
			
		||||
### Description
 | 
			
		||||
 | 
			
		||||
noVNC is both a HTML VNC client JavaScript library and an application built on
 | 
			
		||||
top of that library. noVNC runs well in any modern browser including mobile
 | 
			
		||||
browsers (iOS and Android).
 | 
			
		||||
 | 
			
		||||
Many companies, projects and products have integrated noVNC including
 | 
			
		||||
[OpenStack](http://www.openstack.org),
 | 
			
		||||
[OpenNebula](http://opennebula.org/),
 | 
			
		||||
[LibVNCServer](http://libvncserver.sourceforge.net), and
 | 
			
		||||
[ThinLinc](https://cendio.com/thinlinc). See
 | 
			
		||||
[the Projects and Companies wiki page](https://github.com/novnc/noVNC/wiki/Projects-and-companies-using-noVNC)
 | 
			
		||||
for a more complete list with additional info and links.
 | 
			
		||||
 | 
			
		||||
### Table of Contents
 | 
			
		||||
 | 
			
		||||
- [News/help/contact](#newshelpcontact)
 | 
			
		||||
- [Features](#features)
 | 
			
		||||
- [Screenshots](#screenshots)
 | 
			
		||||
- [Browser Requirements](#browser-requirements)
 | 
			
		||||
- [Server Requirements](#server-requirements)
 | 
			
		||||
- [Quick Start](#quick-start)
 | 
			
		||||
- [Installation from Snap Package](#installation-from-snap-package)
 | 
			
		||||
- [Integration and Deployment](#integration-and-deployment)
 | 
			
		||||
- [Authors/Contributors](#authorscontributors)
 | 
			
		||||
 | 
			
		||||
### News/help/contact
 | 
			
		||||
 | 
			
		||||
The project website is found at [novnc.com](http://novnc.com).
 | 
			
		||||
 | 
			
		||||
If you are a noVNC developer/integrator/user (or want to be) please join the
 | 
			
		||||
[noVNC discussion group](https://groups.google.com/forum/?fromgroups#!forum/novnc).
 | 
			
		||||
 | 
			
		||||
Bugs and feature requests can be submitted via
 | 
			
		||||
[github issues](https://github.com/novnc/noVNC/issues). If you have questions
 | 
			
		||||
about using noVNC then please first use the
 | 
			
		||||
[discussion group](https://groups.google.com/forum/?fromgroups#!forum/novnc).
 | 
			
		||||
We also have a [wiki](https://github.com/novnc/noVNC/wiki/) with lots of
 | 
			
		||||
helpful information.
 | 
			
		||||
 | 
			
		||||
If you are looking for a place to start contributing to noVNC, a good place to
 | 
			
		||||
start would be the issues that are marked as
 | 
			
		||||
["patchwelcome"](https://github.com/novnc/noVNC/issues?labels=patchwelcome).
 | 
			
		||||
Please check our
 | 
			
		||||
[contribution guide](https://github.com/novnc/noVNC/wiki/Contributing) though.
 | 
			
		||||
 | 
			
		||||
If you want to show appreciation for noVNC you could donate to a great non-
 | 
			
		||||
profits such as:
 | 
			
		||||
[Compassion International](http://www.compassion.com/),
 | 
			
		||||
[SIL](http://www.sil.org),
 | 
			
		||||
[Habitat for Humanity](http://www.habitat.org),
 | 
			
		||||
[Electronic Frontier Foundation](https://www.eff.org/),
 | 
			
		||||
[Against Malaria Foundation](http://www.againstmalaria.com/),
 | 
			
		||||
[Nothing But Nets](http://www.nothingbutnets.net/), etc.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Features
 | 
			
		||||
 | 
			
		||||
* Supports all modern browsers including mobile (iOS, Android)
 | 
			
		||||
* Supported authentication methods: none, classical VNC, RealVNC's
 | 
			
		||||
  RSA-AES, Tight, VeNCrypt Plain, XVP, Apple's Diffie-Hellman,
 | 
			
		||||
  UltraVNC's MSLogonII
 | 
			
		||||
* Supported VNC encodings: raw, copyrect, rre, hextile, tight, tightPNG,
 | 
			
		||||
  ZRLE, JPEG
 | 
			
		||||
* Supports scaling, clipping and resizing the desktop
 | 
			
		||||
* Local cursor rendering
 | 
			
		||||
* Clipboard copy/paste with full Unicode support
 | 
			
		||||
* Translations
 | 
			
		||||
* Touch gestures for emulating common mouse actions
 | 
			
		||||
* Licensed mainly under the [MPL 2.0](http://www.mozilla.org/MPL/2.0/), see
 | 
			
		||||
  [the license document](LICENSE.txt) for details
 | 
			
		||||
 | 
			
		||||
### Screenshots
 | 
			
		||||
 | 
			
		||||
Running in Firefox before and after connecting:
 | 
			
		||||
 | 
			
		||||
<img src="http://novnc.com/img/noVNC-1-login.png" width=400> 
 | 
			
		||||
<img src="http://novnc.com/img/noVNC-3-connected.png" width=400>
 | 
			
		||||
 | 
			
		||||
See more screenshots
 | 
			
		||||
[here](http://novnc.com/screenshots.html).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Browser Requirements
 | 
			
		||||
 | 
			
		||||
noVNC uses many modern web technologies so a formal requirement list is
 | 
			
		||||
not available. However these are the minimum versions we are currently
 | 
			
		||||
aware of:
 | 
			
		||||
 | 
			
		||||
* Chrome 64, Firefox 79, Safari 13.4, Opera 51, Edge 79
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Server Requirements
 | 
			
		||||
 | 
			
		||||
noVNC follows the standard VNC protocol, but unlike other VNC clients it does
 | 
			
		||||
require WebSockets support. Many servers include support (e.g.
 | 
			
		||||
[x11vnc/libvncserver](http://libvncserver.sourceforge.net/),
 | 
			
		||||
[QEMU](http://www.qemu.org/), and
 | 
			
		||||
[MobileVNC](http://www.smartlab.at/mobilevnc/)), but for the others you need to
 | 
			
		||||
use a WebSockets to TCP socket proxy. noVNC has a sister project
 | 
			
		||||
[websockify](https://github.com/novnc/websockify) that provides a simple such
 | 
			
		||||
proxy.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Quick Start
 | 
			
		||||
 | 
			
		||||
* Use the `novnc_proxy` script to automatically download and start websockify, which
 | 
			
		||||
  includes a mini-webserver and the WebSockets proxy. The `--vnc` option is
 | 
			
		||||
  used to specify the location of a running VNC server:
 | 
			
		||||
 | 
			
		||||
    `./utils/novnc_proxy --vnc localhost:5901`
 | 
			
		||||
    
 | 
			
		||||
* If you don't need to expose the web server to public internet, you can
 | 
			
		||||
  bind to localhost:
 | 
			
		||||
  
 | 
			
		||||
    `./utils/novnc_proxy --vnc localhost:5901 --listen localhost:6081`
 | 
			
		||||
 | 
			
		||||
* Point your browser to the cut-and-paste URL that is output by the `novnc_proxy`
 | 
			
		||||
  script. Hit the Connect button, enter a password if the VNC server has one
 | 
			
		||||
  configured, and enjoy!
 | 
			
		||||
 | 
			
		||||
### Installation from Snap Package
 | 
			
		||||
Running the command below will install the latest release of noVNC from Snap:
 | 
			
		||||
 | 
			
		||||
`sudo snap install novnc`
 | 
			
		||||
 | 
			
		||||
#### Running noVNC from Snap Directly
 | 
			
		||||
 | 
			
		||||
You can run the Snap-package installed novnc directly with, for example:
 | 
			
		||||
 | 
			
		||||
`novnc --listen 6081 --vnc localhost:5901 # /snap/bin/novnc if /snap/bin is not in your PATH`
 | 
			
		||||
 | 
			
		||||
If you want to use certificate files, due to standard Snap confinement restrictions you need to have them in the /home/\<user\>/snap/novnc/current/ directory. If your username is jsmith an example command would be:
 | 
			
		||||
  
 | 
			
		||||
  `novnc --listen 8443 --cert ~jsmith/snap/novnc/current/self.crt --key ~jsmith/snap/novnc/current/self.key --vnc ubuntu.example.com:5901`
 | 
			
		||||
 | 
			
		||||
#### Running noVNC from Snap as a Service (Daemon)
 | 
			
		||||
The Snap package also has the capability to run a 'novnc' service which can be 
 | 
			
		||||
configured to listen on multiple ports connecting to multiple VNC servers 
 | 
			
		||||
(effectively a service runing multiple instances of novnc).
 | 
			
		||||
Instructions (with example values):
 | 
			
		||||
 | 
			
		||||
List current services (out-of-box this will be blank):
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sudo snap get novnc services
 | 
			
		||||
Key             Value
 | 
			
		||||
services.n6080  {...}
 | 
			
		||||
services.n6081  {...}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Create a new service that listens on port 6082 and connects to the VNC server 
 | 
			
		||||
running on port 5902 on localhost:
 | 
			
		||||
 | 
			
		||||
`sudo snap set novnc services.n6082.listen=6082 services.n6082.vnc=localhost:5902`
 | 
			
		||||
 | 
			
		||||
(Any services you define with 'snap set' will be automatically started)
 | 
			
		||||
Note that the name of the service, 'n6082' in this example, can be anything 
 | 
			
		||||
as long as it doesn't start with a number or contain spaces/special characters.
 | 
			
		||||
 | 
			
		||||
View the configuration of the service just created:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sudo snap get novnc services.n6082
 | 
			
		||||
Key                    Value
 | 
			
		||||
services.n6082.listen  6082
 | 
			
		||||
services.n6082.vnc     localhost:5902
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Disable a service (note that because of a limitation in  Snap it's currently not 
 | 
			
		||||
possible to unset config variables, setting them to blank values is the way 
 | 
			
		||||
to disable a service):
 | 
			
		||||
 | 
			
		||||
`sudo snap set novnc services.n6082.listen='' services.n6082.vnc=''`
 | 
			
		||||
 | 
			
		||||
(Any services you set to blank with 'snap set' like this will be automatically stopped)
 | 
			
		||||
 | 
			
		||||
Verify that the service is disabled (blank values):
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sudo snap get novnc services.n6082
 | 
			
		||||
Key                    Value
 | 
			
		||||
services.n6082.listen  
 | 
			
		||||
services.n6082.vnc
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Integration and Deployment
 | 
			
		||||
 | 
			
		||||
Please see our other documents for how to integrate noVNC in your own software,
 | 
			
		||||
or deploying the noVNC application in production environments:
 | 
			
		||||
 | 
			
		||||
* [Embedding](docs/EMBEDDING.md) - For the noVNC application
 | 
			
		||||
* [Library](docs/LIBRARY.md) - For the noVNC JavaScript library
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Authors/Contributors
 | 
			
		||||
 | 
			
		||||
See [AUTHORS](AUTHORS) for a (full-ish) list of authors.  If you're not on
 | 
			
		||||
that list and you think you should be, feel free to send a PR to fix that.
 | 
			
		||||
 | 
			
		||||
* Core team:
 | 
			
		||||
    * [Samuel Mannehed](https://github.com/samhed) (Cendio)
 | 
			
		||||
    * [Pierre Ossman](https://github.com/CendioOssman) (Cendio)
 | 
			
		||||
 | 
			
		||||
* Previous core contributors:
 | 
			
		||||
    * [Joel Martin](https://github.com/kanaka) (Project founder)
 | 
			
		||||
    * [Solly Ross](https://github.com/DirectXMan12) (Red Hat / OpenStack)
 | 
			
		||||
 | 
			
		||||
* Notable contributions:
 | 
			
		||||
    * UI and Icons : Pierre Ossman, Chris Gordon
 | 
			
		||||
    * Original Logo : Michael Sersen
 | 
			
		||||
    * tight encoding : Michael Tinglof (Mercuri.ca)
 | 
			
		||||
    * RealVNC RSA AES authentication : USTC Vlab Team
 | 
			
		||||
 | 
			
		||||
* Included libraries:
 | 
			
		||||
    * base64 : Martijn Pieters (Digital Creations 2), Samuel Sieb (sieb.net)
 | 
			
		||||
    * DES : Dave Zimmerman (Widget Workshop), Jef Poskanzer (ACME Labs)
 | 
			
		||||
    * Pako : Vitaly Puzrin (https://github.com/nodeca/pako)
 | 
			
		||||
 | 
			
		||||
Do you want to be on this list? Check out our
 | 
			
		||||
[contribution guide](https://github.com/novnc/noVNC/wiki/Contributing) and
 | 
			
		||||
start hacking!
 | 
			
		||||
							
								
								
									
										79
									
								
								VM/novnc/app/error-handler.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,79 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Fallback for all uncought errors
 | 
			
		||||
function handleError(event, err) {
 | 
			
		||||
    try {
 | 
			
		||||
        const msg = document.getElementById('noVNC_fallback_errormsg');
 | 
			
		||||
 | 
			
		||||
        // Work around Firefox bug:
 | 
			
		||||
        // https://bugzilla.mozilla.org/show_bug.cgi?id=1685038
 | 
			
		||||
        if (event.message === "ResizeObserver loop completed with undelivered notifications.") {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Only show the initial error
 | 
			
		||||
        if (msg.hasChildNodes()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let div = document.createElement("div");
 | 
			
		||||
        div.classList.add('noVNC_message');
 | 
			
		||||
        div.appendChild(document.createTextNode(event.message));
 | 
			
		||||
        msg.appendChild(div);
 | 
			
		||||
 | 
			
		||||
        if (event.filename) {
 | 
			
		||||
            div = document.createElement("div");
 | 
			
		||||
            div.className = 'noVNC_location';
 | 
			
		||||
            let text = event.filename;
 | 
			
		||||
            if (event.lineno !== undefined) {
 | 
			
		||||
                text += ":" + event.lineno;
 | 
			
		||||
                if (event.colno !== undefined) {
 | 
			
		||||
                    text += ":" + event.colno;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            div.appendChild(document.createTextNode(text));
 | 
			
		||||
            msg.appendChild(div);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (err && err.stack) {
 | 
			
		||||
            div = document.createElement("div");
 | 
			
		||||
            div.className = 'noVNC_stack';
 | 
			
		||||
            div.appendChild(document.createTextNode(err.stack));
 | 
			
		||||
            msg.appendChild(div);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        document.getElementById('noVNC_fallback_error')
 | 
			
		||||
            .classList.add("noVNC_open");
 | 
			
		||||
 | 
			
		||||
    } catch (exc) {
 | 
			
		||||
        document.write("noVNC encountered an error.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Try to disable keyboard interaction, best effort
 | 
			
		||||
    try {
 | 
			
		||||
        // Remove focus from the currently focused element in order to
 | 
			
		||||
        // prevent keyboard interaction from continuing
 | 
			
		||||
        if (document.activeElement) { document.activeElement.blur(); }
 | 
			
		||||
 | 
			
		||||
        // Don't let any element be focusable when showing the error
 | 
			
		||||
        let keyboardFocusable = 'a[href], button, input, textarea, select, details, [tabindex]';
 | 
			
		||||
        document.querySelectorAll(keyboardFocusable).forEach((elem) => {
 | 
			
		||||
            elem.setAttribute("tabindex", "-1");
 | 
			
		||||
        });
 | 
			
		||||
    } catch (exc) {
 | 
			
		||||
        // Do nothing
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Don't return true since this would prevent the error
 | 
			
		||||
    // from being printed to the browser console.
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.addEventListener('error', evt => handleError(evt, evt.error));
 | 
			
		||||
window.addEventListener('unhandledrejection', evt => handleError(evt.reason, evt.reason));
 | 
			
		||||
							
								
								
									
										92
									
								
								VM/novnc/app/images/alt.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,92 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="alt.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="16"
 | 
			
		||||
     inkscape:cx="18.205425"
 | 
			
		||||
     inkscape:cy="17.531398"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <g
 | 
			
		||||
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
       id="text5290">
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 9.9560547,1042.3329 -2.9394531,0 -0.4638672,1.3281 -1.8896485,0 2.7001953,-7.29 2.241211,0 2.7001958,7.29 -1.889649,0 -0.4589843,-1.3281 z m -2.4707031,-1.3526 1.9970703,0 -0.9960938,-2.9003 -1.0009765,2.9003 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5340" />
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 13.188477,1036.0634 1.748046,0 0,7.5976 -1.748046,0 0,-7.5976 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5342" />
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 18.535156,1036.6395 0,1.5528 1.801758,0 0,1.25 -1.801758,0 0,2.3193 q 0,0.3809 0.151367,0.5176 0.151368,0.1318 0.600586,0.1318 l 0.898438,0 0,1.25 -1.499024,0 q -1.035156,0 -1.469726,-0.4297 -0.429688,-0.4345 -0.429688,-1.4697 l 0,-2.3193 -0.86914,0 0,-1.25 0.86914,0 0,-1.5528 1.748047,0 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5344" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.5 KiB  | 
							
								
								
									
										106
									
								
								VM/novnc/app/images/clipboard.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,106 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="clipboard.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="15.366606"
 | 
			
		||||
     inkscape:cy="16.42981"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="M 9,6 6,6 C 5.4459889,6 5,6.4459889 5,7 l 0,13 c 0,0.554011 0.4459889,1 1,1 l 13,0 c 0.554011,0 1,-0.445989 1,-1 L 20,7 C 20,6.4459889 19.554011,6 19,6 l -3,0"
 | 
			
		||||
       transform="translate(0,1027.3622)"
 | 
			
		||||
       id="rect6083"
 | 
			
		||||
       inkscape:connector-curvature="0"
 | 
			
		||||
       sodipodi:nodetypes="cssssssssc" />
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect6085"
 | 
			
		||||
       width="7"
 | 
			
		||||
       height="4"
 | 
			
		||||
       x="9"
 | 
			
		||||
       y="1031.3622"
 | 
			
		||||
       ry="1.00002" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
 | 
			
		||||
       d="m 8.5071212,1038.8622 7.9999998,0"
 | 
			
		||||
       id="path6087"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
 | 
			
		||||
       d="m 8.5071212,1041.8622 3.9999998,0"
 | 
			
		||||
       id="path6089"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
 | 
			
		||||
       d="m 8.5071212,1044.8622 5.9999998,0"
 | 
			
		||||
       id="path6091"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										96
									
								
								VM/novnc/app/images/connect.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,96 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="connect.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="37.14834"
 | 
			
		||||
     inkscape:cy="1.9525926"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <g
 | 
			
		||||
       id="g5103"
 | 
			
		||||
       transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-729.15757,315.8823)">
 | 
			
		||||
      <path
 | 
			
		||||
         sodipodi:nodetypes="cssssc"
 | 
			
		||||
         inkscape:connector-curvature="0"
 | 
			
		||||
         id="rect5096"
 | 
			
		||||
         d="m 11,1040.3622 -5,0 c -1.108,0 -2,-0.892 -2,-2 l 0,-4 c 0,-1.108 0.892,-2 2,-2 l 5,0"
 | 
			
		||||
         style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 | 
			
		||||
      <path
 | 
			
		||||
         style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
         d="m 14,1032.3622 5,0 c 1.108,0 2,0.892 2,2 l 0,4 c 0,1.108 -0.892,2 -2,2 l -5,0"
 | 
			
		||||
         id="path5099"
 | 
			
		||||
         inkscape:connector-curvature="0"
 | 
			
		||||
         sodipodi:nodetypes="cssssc" />
 | 
			
		||||
      <path
 | 
			
		||||
         inkscape:connector-curvature="0"
 | 
			
		||||
         id="path5101"
 | 
			
		||||
         d="m 9,1036.3622 7,0"
 | 
			
		||||
         style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.3 KiB  | 
							
								
								
									
										96
									
								
								VM/novnc/app/images/ctrl.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,96 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="ctrl.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="16"
 | 
			
		||||
     inkscape:cx="18.205425"
 | 
			
		||||
     inkscape:cy="17.531398"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <g
 | 
			
		||||
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
       id="text5290">
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 9.1210938,1043.1898 q -0.5175782,0.2686 -1.0791016,0.4053 -0.5615235,0.1367 -1.171875,0.1367 -1.8212891,0 -2.8857422,-1.0156 -1.0644531,-1.0205 -1.0644531,-2.7637 0,-1.748 1.0644531,-2.7637 1.0644531,-1.0205 2.8857422,-1.0205 0.6103515,0 1.171875,0.1368 0.5615234,0.1367 1.0791016,0.4052 l 0,1.5088 q -0.522461,-0.3564 -1.0302735,-0.5224 -0.5078125,-0.1661 -1.0693359,-0.1661 -1.0058594,0 -1.5820313,0.6446 -0.5761719,0.6445 -0.5761719,1.7773 0,1.1279 0.5761719,1.7725 0.5761719,0.6445 1.5820313,0.6445 0.5615234,0 1.0693359,-0.166 0.5078125,-0.166 1.0302735,-0.5225 l 0,1.5088 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5370" />
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 12.514648,1036.5687 0,1.5528 1.801758,0 0,1.25 -1.801758,0 0,2.3193 q 0,0.3809 0.151368,0.5176 0.151367,0.1318 0.600586,0.1318 l 0.898437,0 0,1.25 -1.499023,0 q -1.035157,0 -1.469727,-0.4297 -0.429687,-0.4345 -0.429687,-1.4697 l 0,-2.3193 -0.8691411,0 0,-1.25 0.8691411,0 0,-1.5528 1.748046,0 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5372" />
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 19.453125,1039.6107 q -0.229492,-0.1074 -0.458984,-0.1562 -0.22461,-0.054 -0.454102,-0.054 -0.673828,0 -1.040039,0.4345 -0.361328,0.4297 -0.361328,1.2354 l 0,2.5195 -1.748047,0 0,-5.4687 1.748047,0 0,0.8984 q 0.336914,-0.5371 0.771484,-0.7813 0.439453,-0.249 1.049805,-0.249 0.08789,0 0.19043,0.01 0.102539,0 0.297851,0.029 l 0.0049,1.582 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5374" />
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 20.332031,1035.9926 1.748047,0 0,7.5976 -1.748047,0 0,-7.5976 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5376" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
							
								
								
									
										100
									
								
								VM/novnc/app/images/ctrlaltdel.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,100 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="ctrlaltdel.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="8"
 | 
			
		||||
     inkscape:cx="11.135667"
 | 
			
		||||
     inkscape:cy="16.407428"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect5253"
 | 
			
		||||
       width="5"
 | 
			
		||||
       height="5.0000172"
 | 
			
		||||
       x="16"
 | 
			
		||||
       y="1031.3622"
 | 
			
		||||
       ry="1.0000174" />
 | 
			
		||||
    <rect
 | 
			
		||||
       y="1043.3622"
 | 
			
		||||
       x="4"
 | 
			
		||||
       height="5.0000172"
 | 
			
		||||
       width="5"
 | 
			
		||||
       id="rect5255"
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       ry="1.0000174" />
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect5257"
 | 
			
		||||
       width="5"
 | 
			
		||||
       height="5.0000172"
 | 
			
		||||
       x="13"
 | 
			
		||||
       y="1043.3622"
 | 
			
		||||
       ry="1.0000174" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.2 KiB  | 
							
								
								
									
										94
									
								
								VM/novnc/app/images/disconnect.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,94 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="disconnect.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="16"
 | 
			
		||||
     inkscape:cx="25.05707"
 | 
			
		||||
     inkscape:cy="11.594858"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="false">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <g
 | 
			
		||||
       id="g5171"
 | 
			
		||||
       transform="translate(-24.062499,-6.15775e-4)">
 | 
			
		||||
      <path
 | 
			
		||||
         id="path5110"
 | 
			
		||||
         transform="translate(0,1027.3622)"
 | 
			
		||||
         d="m 39.744141,3.4960938 c -0.769923,0 -1.539607,0.2915468 -2.121094,0.8730468 l -2.566406,2.5664063 1.414062,1.4140625 2.566406,-2.5664063 c 0.403974,-0.404 1.010089,-0.404 1.414063,0 l 2.828125,2.828125 c 0.40398,0.4039 0.403907,1.0101621 0,1.4140629 l -2.566406,2.566406 1.414062,1.414062 2.566406,-2.566406 c 1.163041,-1.1629 1.162968,-3.0791874 0,-4.2421874 L 41.865234,4.3691406 C 41.283747,3.7876406 40.514063,3.4960937 39.744141,3.4960938 Z M 39.017578,9.015625 a 1.0001,1.0001 0 0 0 -0.6875,0.3027344 l -0.445312,0.4453125 1.414062,1.4140621 0.445313,-0.445312 A 1.0001,1.0001 0 0 0 39.017578,9.015625 Z m -6.363281,0.7070312 a 1.0001,1.0001 0 0 0 -0.6875,0.3027348 L 28.431641,13.5625 c -1.163042,1.163 -1.16297,3.079187 0,4.242188 l 2.828125,2.828124 c 1.162974,1.163101 3.079213,1.163101 4.242187,0 l 3.535156,-3.535156 a 1.0001,1.0001 0 1 0 -1.414062,-1.414062 l -3.535156,3.535156 c -0.403974,0.404 -1.010089,0.404 -1.414063,0 l -2.828125,-2.828125 c -0.403981,-0.404 -0.403908,-1.010162 0,-1.414063 l 3.535156,-3.537109 A 1.0001,1.0001 0 0 0 32.654297,9.7226562 Z m 3.109375,2.1621098 -2.382813,2.384765 a 1.0001,1.0001 0 1 0 1.414063,1.414063 l 2.382812,-2.384766 -1.414062,-1.414062 z"
 | 
			
		||||
         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
         inkscape:connector-curvature="0" />
 | 
			
		||||
      <rect
 | 
			
		||||
         transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,0,0)"
 | 
			
		||||
         y="752.29541"
 | 
			
		||||
         x="-712.31262"
 | 
			
		||||
         height="18.000017"
 | 
			
		||||
         width="3"
 | 
			
		||||
         id="rect5116"
 | 
			
		||||
         style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										76
									
								
								VM/novnc/app/images/drag.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,76 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="drag.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="22.627417"
 | 
			
		||||
     inkscape:cx="9.8789407"
 | 
			
		||||
     inkscape:cy="9.5008608"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="m 7.039733,1049.3037 c -0.4309106,-0.1233 -0.7932634,-0.4631 -0.9705434,-0.9103 -0.04922,-0.1241 -0.057118,-0.2988 -0.071321,-1.5771 l -0.015972,-1.4375 -0.328125,-0.082 c -0.7668138,-0.1927 -1.1897046,-0.4275 -1.7031253,-0.9457 -0.4586773,-0.4629 -0.6804297,-0.8433 -0.867034,-1.4875 -0.067215,-0.232 -0.068001,-0.2642 -0.078682,-3.2188 -0.012078,-3.341 -0.020337,-3.2012 0.2099452,-3.5555 0.2246623,-0.3458 0.5798271,-0.5892 0.9667343,-0.6626 0.092506,-0.017 0.531898,-0.032 0.9764271,-0.032 l 0.8082347,0 1.157e-4,1.336 c 1.125e-4,1.2779 0.00281,1.3403 0.062214,1.4378 0.091785,0.1505 0.2357707,0.226 0.4314082,0.2261 0.285389,2e-4 0.454884,-0.1352 0.5058962,-0.4042 0.019355,-0.102 0.031616,-0.982 0.031616,-2.269 0,-1.9756 0.00357,-2.1138 0.059205,-2.2926 0.1645475,-0.5287 0.6307616,-0.9246 1.19078,-1.0113 0.8000572,-0.1238 1.5711277,0.4446 1.6860387,1.2429 0.01732,0.1203 0.03177,0.8248 0.03211,1.5657 6.19e-4,1.3449 7.22e-4,1.347 0.07093,1.4499 0.108355,0.1587 0.255268,0.2248 0.46917,0.2108 0.204069,-0.013 0.316116,-0.08 0.413642,-0.2453 0.06028,-0.1024 0.06307,-0.1778 0.07862,-2.1218 0.01462,-1.8283 0.02124,-2.0285 0.07121,-2.1549 0.260673,-0.659 0.934894,-1.0527 1.621129,-0.9465 0.640523,0.099 1.152269,0.6104 1.243187,1.2421 0.01827,0.1269 0.03175,0.9943 0.03211,2.0657 l 6.19e-4,1.8469 0.07031,0.103 c 0.108355,0.1587 0.255267,0.2248 0.46917,0.2108 0.204069,-0.013 0.316115,-0.08 0.413642,-0.2453 0.05951,-0.1011 0.06329,-0.1786 0.07907,-1.6218 0.01469,-1.3438 0.02277,-1.5314 0.07121,-1.6549 0.257975,-0.6576 0.934425,-1.0527 1.620676,-0.9465 0.640522,0.099 1.152269,0.6104 1.243186,1.2421 0.0186,0.1292 0.03179,1.0759 0.03222,2.3125 7.15e-4,2.0335 0.0025,2.0966 0.06283,2.1956 0.09178,0.1505 0.235771,0.226 0.431409,0.2261 0.285388,2e-4 0.454884,-0.1352 0.505897,-0.4042 0.01874,-0.099 0.03161,-0.8192 0.03161,-1.769 0,-1.4848 0.0043,-1.6163 0.0592,-1.7926 0.164548,-0.5287 0.630762,-0.9246 1.19078,-1.0113 0.800057,-0.1238 1.571128,0.4446 1.686039,1.2429 0.04318,0.2999 0.04372,9.1764 5.78e-4,9.4531 -0.04431,0.2841 -0.217814,0.6241 -0.420069,0.8232 -0.320102,0.315 -0.63307,0.4268 -1.194973,0.4268 l -0.35281,0 -2.51e-4,1.2734 c -1.25e-4,0.7046 -0.01439,1.3642 -0.03191,1.4766 -0.06665,0.4274 -0.372966,0.8704 -0.740031,1.0702 -0.349999,0.1905 0.01748,0.18 -6.242199,0.1776 -5.3622439,0 -5.7320152,-0.01 -5.9121592,-0.057 l 1.4e-5,0 z"
 | 
			
		||||
       id="path4379"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 4.6 KiB  | 
							
								
								
									
										81
									
								
								VM/novnc/app/images/error.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,81 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="error.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="14.00357"
 | 
			
		||||
     inkscape:cy="12.443398"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title />
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="M 7 3 C 4.7839905 3 3 4.7839905 3 7 L 3 18 C 3 20.21601 4.7839905 22 7 22 L 18 22 C 20.21601 22 22 20.21601 22 18 L 22 7 C 22 4.7839905 20.21601 3 18 3 L 7 3 z M 7.6992188 6 A 1.6916875 1.6924297 0 0 1 8.9121094 6.5117188 L 12.5 10.101562 L 16.087891 6.5117188 A 1.6916875 1.6924297 0 0 1 17.251953 6 A 1.6916875 1.6924297 0 0 1 18.480469 8.90625 L 14.892578 12.496094 L 18.480469 16.085938 A 1.6916875 1.6924297 0 1 1 16.087891 18.478516 L 12.5 14.888672 L 8.9121094 18.478516 A 1.6916875 1.6924297 0 1 1 6.5214844 16.085938 L 10.109375 12.496094 L 6.5214844 8.90625 A 1.6916875 1.6924297 0 0 1 7.6992188 6 z "
 | 
			
		||||
       transform="translate(0,1027.3622)"
 | 
			
		||||
       id="rect4135" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.0 KiB  | 
							
								
								
									
										92
									
								
								VM/novnc/app/images/esc.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,92 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="esc.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="16"
 | 
			
		||||
     inkscape:cx="18.205425"
 | 
			
		||||
     inkscape:cy="17.531398"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="text5290"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <g
 | 
			
		||||
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
       id="text5290">
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 3.9331055,1036.1464 5.0732422,0 0,1.4209 -3.1933594,0 0,1.3574 3.0029297,0 0,1.4209 -3.0029297,0 0,1.6699 3.3007812,0 0,1.4209 -5.180664,0 0,-7.29 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5314" />
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 14.963379,1038.1385 0,1.3282 q -0.561524,-0.2344 -1.083984,-0.3516 -0.522461,-0.1172 -0.986329,-0.1172 -0.498046,0 -0.742187,0.127 -0.239258,0.122 -0.239258,0.3808 0,0.21 0.180664,0.3223 0.185547,0.1123 0.65918,0.166 l 0.307617,0.044 q 1.342773,0.1709 1.806641,0.5615 0.463867,0.3906 0.463867,1.2256 0,0.874 -0.644531,1.3134 -0.644532,0.4395 -1.923829,0.4395 -0.541992,0 -1.123046,-0.088 -0.576172,-0.083 -1.186524,-0.2539 l 0,-1.3281 q 0.522461,0.2539 1.069336,0.3808 0.551758,0.127 1.118164,0.127 0.512695,0 0.771485,-0.1416 0.258789,-0.1416 0.258789,-0.4199 0,-0.2344 -0.180664,-0.3467 -0.175782,-0.1172 -0.708008,-0.1807 l -0.307617,-0.039 q -1.166993,-0.1465 -1.635743,-0.542 -0.46875,-0.3955 -0.46875,-1.2012 0,-0.8691 0.595703,-1.2891 0.595704,-0.4199 1.826172,-0.4199 0.483399,0 1.015625,0.073 0.532227,0.073 1.157227,0.2294 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5316" />
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 21.066895,1038.1385 0,1.4258 q -0.356446,-0.2441 -0.717774,-0.3613 -0.356445,-0.1172 -0.742187,-0.1172 -0.732422,0 -1.142579,0.4297 -0.405273,0.4248 -0.405273,1.1914 0,0.7666 0.405273,1.1963 0.410157,0.4248 1.142579,0.4248 0.410156,0 0.776367,-0.1221 0.371094,-0.122 0.683594,-0.3613 l 0,1.4307 q -0.410157,0.1513 -0.834961,0.2246 -0.419922,0.078 -0.844727,0.078 -1.479492,0 -2.314453,-0.7568 -0.834961,-0.7618 -0.834961,-2.1143 0,-1.3525 0.834961,-2.1094 0.834961,-0.7617 2.314453,-0.7617 0.429688,0 0.844727,0.078 0.419921,0.073 0.834961,0.2246 z"
 | 
			
		||||
         style="font-size:10px;fill:#ffffff;fill-opacity:1"
 | 
			
		||||
         id="path5318" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 4.4 KiB  | 
							
								
								
									
										69
									
								
								VM/novnc/app/images/expander.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,69 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="9"
 | 
			
		||||
   height="10"
 | 
			
		||||
   viewBox="0 0 9 10"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="expander.svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="45.254834"
 | 
			
		||||
     inkscape:cx="9.8737281"
 | 
			
		||||
     inkscape:cy="6.4583132"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-object-midpoints="false"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="0"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1042.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
       d="M 2.0800781,1042.3633 A 2.0002,2.0002 0 0 0 0,1044.3613 l 0,6 a 2.0002,2.0002 0 0 0 3.0292969,1.7168 l 5,-3 a 2.0002,2.0002 0 0 0 0,-3.4316 l -5,-3 a 2.0002,2.0002 0 0 0 -0.9492188,-0.2832 z"
 | 
			
		||||
       id="path4138"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.0 KiB  | 
							
								
								
									
										93
									
								
								VM/novnc/app/images/fullscreen.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,93 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="fullscreen.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="16.400723"
 | 
			
		||||
     inkscape:cy="15.083758"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="false">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect5006"
 | 
			
		||||
       width="17"
 | 
			
		||||
       height="17.000017"
 | 
			
		||||
       x="4"
 | 
			
		||||
       y="1031.3622"
 | 
			
		||||
       ry="3.0000174" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
 | 
			
		||||
       d="m 7.5,1044.8622 4,0 -1.5,-1.5 1.5,-1.5 -1,-1 -1.5,1.5 -1.5,-1.5 0,4 z"
 | 
			
		||||
       id="path5017"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
    <path
 | 
			
		||||
       inkscape:connector-curvature="0"
 | 
			
		||||
       id="path5025"
 | 
			
		||||
       d="m 17.5,1034.8622 -4,0 1.5,1.5 -1.5,1.5 1,1 1.5,-1.5 1.5,1.5 0,-4 z"
 | 
			
		||||
       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.1 KiB  | 
							
								
								
									
										82
									
								
								VM/novnc/app/images/handle.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,82 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="5"
 | 
			
		||||
   height="6"
 | 
			
		||||
   viewBox="0 0 5 6"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="handle.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="32"
 | 
			
		||||
     inkscape:cx="1.3551778"
 | 
			
		||||
     inkscape:cy="8.7800329"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1046.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 | 
			
		||||
       d="m 4.0000803,1049.3622 -3,-2 0,4 z"
 | 
			
		||||
       id="path4247"
 | 
			
		||||
       inkscape:connector-curvature="0"
 | 
			
		||||
       sodipodi:nodetypes="cccc" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.5 KiB  | 
							
								
								
									
										172
									
								
								VM/novnc/app/images/handle_bg.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,172 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="15"
 | 
			
		||||
   height="50"
 | 
			
		||||
   viewBox="0 0 15 50"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="handle_bg.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="16"
 | 
			
		||||
     inkscape:cx="-10.001409"
 | 
			
		||||
     inkscape:cy="24.512566"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1002.3622)">
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4249"
 | 
			
		||||
       width="1"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       x="9.5"
 | 
			
		||||
       y="1008.8622"
 | 
			
		||||
       ry="1.7382812e-05" />
 | 
			
		||||
    <rect
 | 
			
		||||
       ry="1.7382812e-05"
 | 
			
		||||
       y="1013.8622"
 | 
			
		||||
       x="9.5"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       width="1"
 | 
			
		||||
       id="rect4255"
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 | 
			
		||||
    <rect
 | 
			
		||||
       ry="1.7382812e-05"
 | 
			
		||||
       y="1008.8622"
 | 
			
		||||
       x="4.5"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       width="1"
 | 
			
		||||
       id="rect4261"
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4263"
 | 
			
		||||
       width="1"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       x="4.5"
 | 
			
		||||
       y="1013.8622"
 | 
			
		||||
       ry="1.7382812e-05" />
 | 
			
		||||
    <rect
 | 
			
		||||
       ry="1.7382812e-05"
 | 
			
		||||
       y="1039.8622"
 | 
			
		||||
       x="9.5"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       width="1"
 | 
			
		||||
       id="rect4265"
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4267"
 | 
			
		||||
       width="1"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       x="9.5"
 | 
			
		||||
       y="1044.8622"
 | 
			
		||||
       ry="1.7382812e-05" />
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4269"
 | 
			
		||||
       width="1"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       x="4.5"
 | 
			
		||||
       y="1039.8622"
 | 
			
		||||
       ry="1.7382812e-05" />
 | 
			
		||||
    <rect
 | 
			
		||||
       ry="1.7382812e-05"
 | 
			
		||||
       y="1044.8622"
 | 
			
		||||
       x="4.5"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       width="1"
 | 
			
		||||
       id="rect4271"
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4273"
 | 
			
		||||
       width="1"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       x="9.5"
 | 
			
		||||
       y="1018.8622"
 | 
			
		||||
       ry="1.7382812e-05" />
 | 
			
		||||
    <rect
 | 
			
		||||
       ry="1.7382812e-05"
 | 
			
		||||
       y="1018.8622"
 | 
			
		||||
       x="4.5"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       width="1"
 | 
			
		||||
       id="rect4275"
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4277"
 | 
			
		||||
       width="1"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       x="9.5"
 | 
			
		||||
       y="1034.8622"
 | 
			
		||||
       ry="1.7382812e-05" />
 | 
			
		||||
    <rect
 | 
			
		||||
       ry="1.7382812e-05"
 | 
			
		||||
       y="1034.8622"
 | 
			
		||||
       x="4.5"
 | 
			
		||||
       height="1.0000174"
 | 
			
		||||
       width="1"
 | 
			
		||||
       id="rect4279"
 | 
			
		||||
       style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 6.2 KiB  | 
							
								
								
									
										42
									
								
								VM/novnc/app/images/icons/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,42 @@
 | 
			
		||||
BROWSER_SIZES := 16 24 32 48 64
 | 
			
		||||
#ANDROID_SIZES := 72 96 144 192
 | 
			
		||||
# FIXME: The ICO is limited to 8 icons due to a Chrome bug:
 | 
			
		||||
#        https://bugs.chromium.org/p/chromium/issues/detail?id=1381393
 | 
			
		||||
ANDROID_SIZES := 96 144 192
 | 
			
		||||
WEB_ICON_SIZES := $(BROWSER_SIZES) $(ANDROID_SIZES)
 | 
			
		||||
 | 
			
		||||
#IOS_1X_SIZES := 20 29 40 76 # No such devices exist anymore
 | 
			
		||||
IOS_2X_SIZES := 40 58 80 120 152 167
 | 
			
		||||
IOS_3X_SIZES := 60 87 120 180
 | 
			
		||||
ALL_IOS_SIZES := $(IOS_1X_SIZES) $(IOS_2X_SIZES) $(IOS_3X_SIZES)
 | 
			
		||||
 | 
			
		||||
ALL_ICONS := \
 | 
			
		||||
	$(ALL_IOS_SIZES:%=novnc-ios-%.png) \
 | 
			
		||||
	novnc.ico
 | 
			
		||||
 | 
			
		||||
all: $(ALL_ICONS)
 | 
			
		||||
 | 
			
		||||
# Our testing shows that the ICO file need to be sorted in largest to
 | 
			
		||||
# smallest to get the apporpriate behviour
 | 
			
		||||
WEB_ICON_SIZES_REVERSE := $(shell echo $(WEB_ICON_SIZES) | tr ' ' '\n' | sort -nr | tr '\n' ' ')
 | 
			
		||||
WEB_BASE_ICONS := $(WEB_ICON_SIZES_REVERSE:%=novnc-%.png)
 | 
			
		||||
.INTERMEDIATE: $(WEB_BASE_ICONS)
 | 
			
		||||
 | 
			
		||||
novnc.ico: $(WEB_BASE_ICONS)
 | 
			
		||||
	convert $(WEB_BASE_ICONS) "$@"
 | 
			
		||||
 | 
			
		||||
# General conversion
 | 
			
		||||
novnc-%.png: novnc-icon.svg
 | 
			
		||||
	convert -depth 8 -background transparent \
 | 
			
		||||
		-size $*x$* "$(lastword $^)" "$@"
 | 
			
		||||
 | 
			
		||||
# iOS icons use their own SVG
 | 
			
		||||
novnc-ios-%.png: novnc-ios-icon.svg
 | 
			
		||||
	convert -depth 8 -background transparent \
 | 
			
		||||
		-size $*x$* "$(lastword $^)" "$@"
 | 
			
		||||
 | 
			
		||||
# The smallest sizes are generated using a different SVG
 | 
			
		||||
novnc-16.png novnc-24.png novnc-32.png: novnc-icon-sm.svg
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.png
 | 
			
		||||
							
								
								
									
										163
									
								
								VM/novnc/app/images/icons/novnc-icon-sm.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,163 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="16"
 | 
			
		||||
   height="16"
 | 
			
		||||
   viewBox="0 0 16 16"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="novnc-icon-sm.svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="45.254834"
 | 
			
		||||
     inkscape:cx="9.722703"
 | 
			
		||||
     inkscape:cy="5.5311896"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:snap-midpoints="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4169" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1036.3621)">
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:1;fill:#494949;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4167"
 | 
			
		||||
       width="16"
 | 
			
		||||
       height="15.999992"
 | 
			
		||||
       x="0"
 | 
			
		||||
       y="1036.3622"
 | 
			
		||||
       ry="2.6666584" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:#313131;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="M 2.6666667,1036.3621 C 1.1893373,1036.3621 0,1037.5515 0,1039.0288 l 0,10.6666 c 0,1.4774 1.1893373,2.6667 2.6666667,2.6667 l 4,0 C 11.837333,1052.3621 16,1046.7128 16,1039.6955 l 0,-0.6667 c 0,-1.4773 -1.189337,-2.6667 -2.666667,-2.6667 l -10.6666663,0 z"
 | 
			
		||||
       id="rect4173"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
    <g
 | 
			
		||||
       id="g4381">
 | 
			
		||||
      <g
 | 
			
		||||
         transform="translate(0.25,0.25)"
 | 
			
		||||
         style="fill:#000000;fill-opacity:1"
 | 
			
		||||
         id="g4365">
 | 
			
		||||
        <g
 | 
			
		||||
           style="fill:#000000;fill-opacity:1"
 | 
			
		||||
           id="g4367">
 | 
			
		||||
          <path
 | 
			
		||||
             inkscape:connector-curvature="0"
 | 
			
		||||
             id="path4369"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             d="m 4.3289754,1039.3621 c 0.1846149,0 0.3419956,0.071 0.4716623,0.2121 C 4.933546,1039.7121 5,1039.8793 5,1040.0759 l 0,3.2862 -1,0 0,-2.964 c 0,-0.024 -0.011592,-0.036 -0.034038,-0.036 l -1.931924,0 C 2.011349,1040.3621 2,1040.3741 2,1040.3981 l 0,2.964 -1,0 0,-4 z"
 | 
			
		||||
             sodipodi:nodetypes="scsccsssscccs" />
 | 
			
		||||
          <path
 | 
			
		||||
             inkscape:connector-curvature="0"
 | 
			
		||||
             id="path4371"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             d="m 6.6710244,1039.3621 2.6579513,0 c 0.184775,0 0.3419957,0.071 0.471662,0.2121 C 9.933546,1039.7121 10,1039.8793 10,1040.0759 l 0,2.5724 c 0,0.1966 -0.066454,0.3655 -0.1993623,0.5069 -0.1296663,0.1379 -0.286887,0.2069 -0.471662,0.2069 l -2.6579513,0 c -0.184775,0 -0.3436164,-0.069 -0.4765247,-0.2069 C 6.0648334,1043.0138 6,1042.8449 6,1042.6483 l 0,-2.5724 c 0,-0.1966 0.064833,-0.3638 0.1944997,-0.5017 0.1329083,-0.1414 0.2917497,-0.2121 0.4765247,-0.2121 z m 2.2949386,1 -1.931926,0 C 7.011344,1040.3621 7,1040.3741 7,1040.3981 l 0,1.928 c 0,0.024 0.011347,0.036 0.034037,0.036 l 1.931926,0 c 0.02269,0 0.034037,-0.012 0.034037,-0.036 l 0,-1.928 c 0,-0.024 -0.011347,-0.036 -0.034037,-0.036 z"
 | 
			
		||||
             sodipodi:nodetypes="sscsscsscsscssssssssss" />
 | 
			
		||||
        </g>
 | 
			
		||||
        <g
 | 
			
		||||
           style="fill:#000000;fill-opacity:1"
 | 
			
		||||
           id="g4373">
 | 
			
		||||
          <path
 | 
			
		||||
             inkscape:connector-curvature="0"
 | 
			
		||||
             id="path4375"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             d="m 3,1047.1121 1,-2.75 1,0 -1.5,4 -1,0 -1.5,-4 1,0 z"
 | 
			
		||||
             sodipodi:nodetypes="cccccccc" />
 | 
			
		||||
          <path
 | 
			
		||||
             inkscape:connector-curvature="0"
 | 
			
		||||
             id="path4377"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             d="m 9,1046.8621 0,-2.5 1,0 0,4 -1,0 -2,-2.5 0,2.5 -1,0 0,-4 1,0 z"
 | 
			
		||||
             sodipodi:nodetypes="ccccccccccc" />
 | 
			
		||||
          <path
 | 
			
		||||
             inkscape:connector-curvature="0"
 | 
			
		||||
             id="path4379"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             d="m 15,1045.3621 -2.96596,0 c -0.02269,0 -0.03404,0.012 -0.03404,0.036 l 0,1.928 c 0,0.024 0.01135,0.036 0.03404,0.036 l 2.96596,0 0,1 -3.324113,0 c -0.188017,0 -0.348479,-0.068 -0.481388,-0.2037 C 11.064833,1048.0192 11,1047.8511 11,1047.6542 l 0,-2.5842 c 0,-0.1969 0.06483,-0.3633 0.194499,-0.4991 0.132909,-0.1392 0.293371,-0.2088 0.481388,-0.2088 l 3.324113,0 z"
 | 
			
		||||
             sodipodi:nodetypes="cssssccscsscscc" />
 | 
			
		||||
        </g>
 | 
			
		||||
      </g>
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4356">
 | 
			
		||||
        <g
 | 
			
		||||
           id="g4347">
 | 
			
		||||
          <path
 | 
			
		||||
             sodipodi:nodetypes="scsccsssscccs"
 | 
			
		||||
             d="m 4.3289754,1039.3621 c 0.1846149,0 0.3419956,0.071 0.4716623,0.2121 C 4.933546,1039.7121 5,1039.8793 5,1040.0759 l 0,3.2862 -1,0 0,-2.964 c 0,-0.024 -0.011592,-0.036 -0.034038,-0.036 l -1.931924,0 c -0.022689,0 -0.034038,0.012 -0.034038,0.036 l 0,2.964 -1,0 0,-4 z"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             id="path4143"
 | 
			
		||||
             inkscape:connector-curvature="0" />
 | 
			
		||||
          <path
 | 
			
		||||
             sodipodi:nodetypes="sscsscsscsscssssssssss"
 | 
			
		||||
             d="m 6.6710244,1039.3621 2.6579513,0 c 0.184775,0 0.3419957,0.071 0.471662,0.2121 C 9.933546,1039.7121 10,1039.8793 10,1040.0759 l 0,2.5724 c 0,0.1966 -0.066454,0.3655 -0.1993623,0.5069 -0.1296663,0.1379 -0.286887,0.2069 -0.471662,0.2069 l -2.6579513,0 c -0.184775,0 -0.3436164,-0.069 -0.4765247,-0.2069 C 6.0648334,1043.0138 6,1042.8449 6,1042.6483 l 0,-2.5724 c 0,-0.1966 0.064833,-0.3638 0.1944997,-0.5017 0.1329083,-0.1414 0.2917497,-0.2121 0.4765247,-0.2121 z m 2.2949386,1 -1.931926,0 C 7.011344,1040.3621 7,1040.3741 7,1040.3981 l 0,1.928 c 0,0.024 0.011347,0.036 0.034037,0.036 l 1.931926,0 c 0.02269,0 0.034037,-0.012 0.034037,-0.036 l 0,-1.928 c 0,-0.024 -0.011347,-0.036 -0.034037,-0.036 z"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             id="path4145"
 | 
			
		||||
             inkscape:connector-curvature="0" />
 | 
			
		||||
        </g>
 | 
			
		||||
        <g
 | 
			
		||||
           id="g4351">
 | 
			
		||||
          <path
 | 
			
		||||
             sodipodi:nodetypes="cccccccc"
 | 
			
		||||
             d="m 3,1047.1121 1,-2.75 1,0 -1.5,4 -1,0 -1.5,-4 1,0 z"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             id="path4147"
 | 
			
		||||
             inkscape:connector-curvature="0" />
 | 
			
		||||
          <path
 | 
			
		||||
             sodipodi:nodetypes="ccccccccccc"
 | 
			
		||||
             d="m 9,1046.8621 0,-2.5 1,0 0,4 -1,0 -2,-2.5 0,2.5 -1,0 0,-4 1,0 z"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             id="path4149"
 | 
			
		||||
             inkscape:connector-curvature="0" />
 | 
			
		||||
          <path
 | 
			
		||||
             sodipodi:nodetypes="cssssccscsscscc"
 | 
			
		||||
             d="m 15,1045.3621 -2.96596,0 c -0.02269,0 -0.03404,0.012 -0.03404,0.036 l 0,1.928 c 0,0.024 0.01135,0.036 0.03404,0.036 l 2.96596,0 0,1 -3.324113,0 c -0.188017,0 -0.348479,-0.068 -0.481388,-0.2037 C 11.064833,1048.0192 11,1047.8511 11,1047.6542 l 0,-2.5842 c 0,-0.1969 0.06483,-0.3633 0.194499,-0.4991 0.132909,-0.1392 0.293371,-0.2088 0.481388,-0.2088 l 3.324113,0 z"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
             id="path4151"
 | 
			
		||||
             inkscape:connector-curvature="0" />
 | 
			
		||||
        </g>
 | 
			
		||||
      </g>
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										163
									
								
								VM/novnc/app/images/icons/novnc-icon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,163 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="48"
 | 
			
		||||
   height="48"
 | 
			
		||||
   viewBox="0 0 48 48.000001"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="novnc-icon.svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="11.313708"
 | 
			
		||||
     inkscape:cx="27.187245"
 | 
			
		||||
     inkscape:cy="17.700974"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:snap-midpoints="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4169" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title />
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1004.3621)">
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:1;fill:#494949;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4167"
 | 
			
		||||
       width="48"
 | 
			
		||||
       height="48"
 | 
			
		||||
       x="0"
 | 
			
		||||
       y="1004.3621"
 | 
			
		||||
       ry="7.9999785" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:#313131;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="m 8,1004.3621 c -4.4319881,0 -8,3.568 -8,8 l 0,32 c 0,4.432 3.5680119,8 8,8 l 12,0 c 15.512,0 28,-16.948 28,-38 l 0,-2 c 0,-4.432 -3.568012,-8 -8,-8 l -32,0 z"
 | 
			
		||||
       id="rect4173"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
    <g
 | 
			
		||||
       id="g4300"
 | 
			
		||||
       style="fill:#000000;fill-opacity:1;stroke:none"
 | 
			
		||||
       transform="translate(0.5,0.5)">
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4302"
 | 
			
		||||
         style="fill:#000000;fill-opacity:1;stroke:none">
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="scsccsssscccs"
 | 
			
		||||
           d="m 11.986926,1016.3621 c 0.554325,0 1.025987,0.2121 1.414987,0.6362 0.398725,0.4138 0.600909,0.9155 0.598087,1.5052 l 0,6.8586 -2,0 0,-6.8914 c 0,-0.072 -0.03404,-0.1086 -0.102113,-0.1086 l -4.7957745,0 C 7.0340375,1018.3621 7,1018.3983 7,1018.4707 l 0,6.8914 -2,0 0,-9 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4304"
 | 
			
		||||
           inkscape:connector-curvature="0" />
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="sscsscsscsscssssssssss"
 | 
			
		||||
           d="m 17.013073,1016.3621 4.973854,0 c 0.554325,0 1.025987,0.2121 1.414986,0.6362 0.398725,0.4138 0.598087,0.9155 0.598087,1.5052 l 0,4.7172 c 0,0.5897 -0.199362,1.0966 -0.598087,1.5207 -0.388999,0.4138 -0.860661,0.6207 -1.414986,0.6207 l -4.973854,0 c -0.554325,0 -1.030849,-0.2069 -1.429574,-0.6207 C 15.1945,1024.3173 15,1023.8104 15,1023.2207 l 0,-4.7172 c 0,-0.5897 0.1945,-1.0914 0.583499,-1.5052 0.398725,-0.4241 0.875249,-0.6362 1.429574,-0.6362 z m 4.884815,2 -4.795776,0 c -0.06808,0 -0.102112,0.036 -0.102112,0.1086 l 0,4.7828 c 0,0.072 0.03404,0.1086 0.102112,0.1086 l 4.795776,0 c 0.06807,0 0.102112,-0.036 0.102112,-0.1086 l 0,-4.7828 c 0,-0.072 -0.03404,-0.1086 -0.102112,-0.1086 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4306"
 | 
			
		||||
           inkscape:connector-curvature="0" />
 | 
			
		||||
      </g>
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4308"
 | 
			
		||||
         style="fill:#000000;fill-opacity:1;stroke:none">
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="cccccccc"
 | 
			
		||||
           d="m 12,1036.9177 4.768114,-8.5556 2.231886,0 -6,11 -2,0 -6,-11 2.2318854,0 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4310"
 | 
			
		||||
           inkscape:connector-curvature="0" />
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="ccccccccccc"
 | 
			
		||||
           d="m 29,1036.3621 0,-8 2,0 0,11 -2,0 -7,-8 0,8 -2,0 0,-11 2,0 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4312"
 | 
			
		||||
           inkscape:connector-curvature="0" />
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="cssssccscsscscc"
 | 
			
		||||
           d="m 43,1030.3621 -8.897887,0 c -0.06808,0 -0.102113,0.036 -0.102113,0.1069 l 0,6.7862 c 0,0.071 0.03404,0.1069 0.102113,0.1069 l 8.897887,0 0,2 -8.972339,0 c -0.56405,0 -1.045437,-0.2037 -1.444162,-0.6111 C 32.1945,1038.3334 32,1037.8292 32,1037.2385 l 0,-6.7528 c 0,-0.5907 0.1945,-1.0898 0.583499,-1.4972 0.398725,-0.4176 0.880112,-0.6264 1.444162,-0.6264 l 8.972339,0 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4314"
 | 
			
		||||
           inkscape:connector-curvature="0" />
 | 
			
		||||
      </g>
 | 
			
		||||
    </g>
 | 
			
		||||
    <g
 | 
			
		||||
       id="g4291"
 | 
			
		||||
       style="stroke:none">
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4282"
 | 
			
		||||
         style="stroke:none">
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4143"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 11.986926,1016.3621 c 0.554325,0 1.025987,0.2121 1.414987,0.6362 0.398725,0.4138 0.600909,0.9155 0.598087,1.5052 l 0,6.8586 -2,0 0,-6.8914 c 0,-0.072 -0.03404,-0.1086 -0.102113,-0.1086 l -4.7957745,0 C 7.0340375,1018.3621 7,1018.3983 7,1018.4707 l 0,6.8914 -2,0 0,-9 z"
 | 
			
		||||
           sodipodi:nodetypes="scsccsssscccs" />
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4145"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 17.013073,1016.3621 4.973854,0 c 0.554325,0 1.025987,0.2121 1.414986,0.6362 0.398725,0.4138 0.598087,0.9155 0.598087,1.5052 l 0,4.7172 c 0,0.5897 -0.199362,1.0966 -0.598087,1.5207 -0.388999,0.4138 -0.860661,0.6207 -1.414986,0.6207 l -4.973854,0 c -0.554325,0 -1.030849,-0.2069 -1.429574,-0.6207 C 15.1945,1024.3173 15,1023.8104 15,1023.2207 l 0,-4.7172 c 0,-0.5897 0.1945,-1.0914 0.583499,-1.5052 0.398725,-0.4241 0.875249,-0.6362 1.429574,-0.6362 z m 4.884815,2 -4.795776,0 c -0.06808,0 -0.102112,0.036 -0.102112,0.1086 l 0,4.7828 c 0,0.072 0.03404,0.1086 0.102112,0.1086 l 4.795776,0 c 0.06807,0 0.102112,-0.036 0.102112,-0.1086 l 0,-4.7828 c 0,-0.072 -0.03404,-0.1086 -0.102112,-0.1086 z"
 | 
			
		||||
           sodipodi:nodetypes="sscsscsscsscssssssssss" />
 | 
			
		||||
      </g>
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4286"
 | 
			
		||||
         style="stroke:none">
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4147"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 12,1036.9177 4.768114,-8.5556 2.231886,0 -6,11 -2,0 -6,-11 2.2318854,0 z"
 | 
			
		||||
           sodipodi:nodetypes="cccccccc" />
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4149"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 29,1036.3621 0,-8 2,0 0,11 -2,0 -7,-8 0,8 -2,0 0,-11 2,0 z"
 | 
			
		||||
           sodipodi:nodetypes="ccccccccccc" />
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4151"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 43,1030.3621 -8.897887,0 c -0.06808,0 -0.102113,0.036 -0.102113,0.1069 l 0,6.7862 c 0,0.071 0.03404,0.1069 0.102113,0.1069 l 8.897887,0 0,2 -8.972339,0 c -0.56405,0 -1.045437,-0.2037 -1.444162,-0.6111 C 32.1945,1038.3334 32,1037.8292 32,1037.2385 l 0,-6.7528 c 0,-0.5907 0.1945,-1.0898 0.583499,-1.4972 0.398725,-0.4176 0.880112,-0.6264 1.444162,-0.6264 l 8.972339,0 z"
 | 
			
		||||
           sodipodi:nodetypes="cssssccscsscscc" />
 | 
			
		||||
      </g>
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-120.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-152.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-167.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-180.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-40.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-58.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-60.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-80.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc-ios-87.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.6 KiB  | 
							
								
								
									
										183
									
								
								VM/novnc/app/images/icons/novnc-ios-icon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,183 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   width="48"
 | 
			
		||||
   height="48"
 | 
			
		||||
   viewBox="0 0 48 48.000001"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
 | 
			
		||||
   sodipodi:docname="novnc-ios-icon.svg"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="11.313708"
 | 
			
		||||
     inkscape:cx="27.356195"
 | 
			
		||||
     inkscape:cy="17.810253"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:snap-midpoints="true"
 | 
			
		||||
     inkscape:window-width="2560"
 | 
			
		||||
     inkscape:window-height="1371"
 | 
			
		||||
     inkscape:window-x="0"
 | 
			
		||||
     inkscape:window-y="0"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:showpageshadow="2"
 | 
			
		||||
     inkscape:pagecheckerboard="0"
 | 
			
		||||
     inkscape:deskcolor="#d1d1d1">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4169" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1004.3621)">
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:1;fill:#494949;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       id="rect4167"
 | 
			
		||||
       width="48"
 | 
			
		||||
       height="48"
 | 
			
		||||
       x="0"
 | 
			
		||||
       y="1004.3621"
 | 
			
		||||
       inkscape:label="background" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:#313131;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="m 0,1004.3621 v 48 h 20 c 15.512,0 28,-16.948 28,-38 v -10 z"
 | 
			
		||||
       id="rect4173"
 | 
			
		||||
       inkscape:connector-curvature="0"
 | 
			
		||||
       sodipodi:nodetypes="cccccc"
 | 
			
		||||
       inkscape:label="darker_grey_plate" />
 | 
			
		||||
    <g
 | 
			
		||||
       id="g4300"
 | 
			
		||||
       style="display:inline;fill:#000000;fill-opacity:1;stroke:none"
 | 
			
		||||
       transform="translate(0.5,0.5)"
 | 
			
		||||
       inkscape:label="shadows">
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4302"
 | 
			
		||||
         style="fill:#000000;fill-opacity:1;stroke:none"
 | 
			
		||||
         inkscape:label="no">
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="scsccsssscccs"
 | 
			
		||||
           d="m 11.986926,1016.3621 c 0.554325,0 1.025987,0.2121 1.414987,0.6362 0.398725,0.4138 0.600909,0.9155 0.598087,1.5052 v 6.8586 h -2 v -6.8914 c 0,-0.072 -0.03404,-0.1086 -0.102113,-0.1086 H 7.1021125 C 7.0340375,1018.3621 7,1018.3983 7,1018.4707 v 6.8914 H 5 v -9 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4304"
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           inkscape:label="n" />
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="sscsscsscsscssssssssss"
 | 
			
		||||
           d="m 17.013073,1016.3621 h 4.973854 c 0.554325,0 1.025987,0.2121 1.414986,0.6362 0.398725,0.4138 0.598087,0.9155 0.598087,1.5052 v 4.7172 c 0,0.5897 -0.199362,1.0966 -0.598087,1.5207 -0.388999,0.4138 -0.860661,0.6207 -1.414986,0.6207 h -4.973854 c -0.554325,0 -1.030849,-0.2069 -1.429574,-0.6207 C 15.1945,1024.3173 15,1023.8104 15,1023.2207 v -4.7172 c 0,-0.5897 0.1945,-1.0914 0.583499,-1.5052 0.398725,-0.4241 0.875249,-0.6362 1.429574,-0.6362 z m 4.884815,2 h -4.795776 c -0.06808,0 -0.102112,0.036 -0.102112,0.1086 v 4.7828 c 0,0.072 0.03404,0.1086 0.102112,0.1086 h 4.795776 c 0.06807,0 0.102112,-0.036 0.102112,-0.1086 v -4.7828 c 0,-0.072 -0.03404,-0.1086 -0.102112,-0.1086 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4306"
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           inkscape:label="o" />
 | 
			
		||||
      </g>
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4308"
 | 
			
		||||
         style="fill:#000000;fill-opacity:1;stroke:none"
 | 
			
		||||
         inkscape:label="VNC">
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="cccccccc"
 | 
			
		||||
           d="m 12,1036.9177 4.768114,-8.5556 H 19 l -6,11 h -2 l -6,-11 h 2.2318854 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4310"
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           inkscape:label="V" />
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="ccccccccccc"
 | 
			
		||||
           d="m 29,1036.3621 v -8 h 2 v 11 h -2 l -7,-8 v 8 h -2 v -11 h 2 z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4312"
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           inkscape:label="N" />
 | 
			
		||||
        <path
 | 
			
		||||
           sodipodi:nodetypes="cssssccscsscscc"
 | 
			
		||||
           d="m 43,1030.3621 h -8.897887 c -0.06808,0 -0.102113,0.036 -0.102113,0.1069 v 6.7862 c 0,0.071 0.03404,0.1069 0.102113,0.1069 H 43 v 2 h -8.972339 c -0.56405,0 -1.045437,-0.2037 -1.444162,-0.6111 C 32.1945,1038.3334 32,1037.8292 32,1037.2385 v -6.7528 c 0,-0.5907 0.1945,-1.0898 0.583499,-1.4972 0.398725,-0.4176 0.880112,-0.6264 1.444162,-0.6264 H 43 Z"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           id="path4314"
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           inkscape:label="C" />
 | 
			
		||||
      </g>
 | 
			
		||||
    </g>
 | 
			
		||||
    <g
 | 
			
		||||
       id="g4291"
 | 
			
		||||
       style="stroke:none"
 | 
			
		||||
       inkscape:label="noVNC">
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4282"
 | 
			
		||||
         style="stroke:none"
 | 
			
		||||
         inkscape:label="no">
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4143"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 11.986926,1016.3621 c 0.554325,0 1.025987,0.2121 1.414987,0.6362 0.398725,0.4138 0.600909,0.9155 0.598087,1.5052 l 0,6.8586 -2,0 0,-6.8914 c 0,-0.072 -0.03404,-0.1086 -0.102113,-0.1086 l -4.7957745,0 C 7.0340375,1018.3621 7,1018.3983 7,1018.4707 l 0,6.8914 -2,0 0,-9 z"
 | 
			
		||||
           sodipodi:nodetypes="scsccsssscccs"
 | 
			
		||||
           inkscape:label="n" />
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4145"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 17.013073,1016.3621 4.973854,0 c 0.554325,0 1.025987,0.2121 1.414986,0.6362 0.398725,0.4138 0.598087,0.9155 0.598087,1.5052 l 0,4.7172 c 0,0.5897 -0.199362,1.0966 -0.598087,1.5207 -0.388999,0.4138 -0.860661,0.6207 -1.414986,0.6207 l -4.973854,0 c -0.554325,0 -1.030849,-0.2069 -1.429574,-0.6207 C 15.1945,1024.3173 15,1023.8104 15,1023.2207 l 0,-4.7172 c 0,-0.5897 0.1945,-1.0914 0.583499,-1.5052 0.398725,-0.4241 0.875249,-0.6362 1.429574,-0.6362 z m 4.884815,2 -4.795776,0 c -0.06808,0 -0.102112,0.036 -0.102112,0.1086 l 0,4.7828 c 0,0.072 0.03404,0.1086 0.102112,0.1086 l 4.795776,0 c 0.06807,0 0.102112,-0.036 0.102112,-0.1086 l 0,-4.7828 c 0,-0.072 -0.03404,-0.1086 -0.102112,-0.1086 z"
 | 
			
		||||
           sodipodi:nodetypes="sscsscsscsscssssssssss"
 | 
			
		||||
           inkscape:label="o" />
 | 
			
		||||
      </g>
 | 
			
		||||
      <g
 | 
			
		||||
         id="g4286"
 | 
			
		||||
         style="stroke:none"
 | 
			
		||||
         inkscape:label="VNC">
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4147"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 12,1036.9177 4.768114,-8.5556 2.231886,0 -6,11 -2,0 -6,-11 2.2318854,0 z"
 | 
			
		||||
           sodipodi:nodetypes="cccccccc"
 | 
			
		||||
           inkscape:label="V" />
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4149"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 29,1036.3621 0,-8 2,0 0,11 -2,0 -7,-8 0,8 -2,0 0,-11 2,0 z"
 | 
			
		||||
           sodipodi:nodetypes="ccccccccccc"
 | 
			
		||||
           inkscape:label="N" />
 | 
			
		||||
        <path
 | 
			
		||||
           inkscape:connector-curvature="0"
 | 
			
		||||
           id="path4151"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           d="m 43,1030.3621 -8.897887,0 c -0.06808,0 -0.102113,0.036 -0.102113,0.1069 l 0,6.7862 c 0,0.071 0.03404,0.1069 0.102113,0.1069 l 8.897887,0 0,2 -8.972339,0 c -0.56405,0 -1.045437,-0.2037 -1.444162,-0.6111 C 32.1945,1038.3334 32,1037.8292 32,1037.2385 l 0,-6.7528 c 0,-0.5907 0.1945,-1.0898 0.583499,-1.4972 0.398725,-0.4176 0.880112,-0.6264 1.444162,-0.6264 l 8.972339,0 z"
 | 
			
		||||
           sodipodi:nodetypes="cssssccscsscscc"
 | 
			
		||||
           inkscape:label="C" />
 | 
			
		||||
      </g>
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 12 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/images/icons/novnc.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 303 KiB  | 
							
								
								
									
										81
									
								
								VM/novnc/app/images/info.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,81 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="info.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="15.720838"
 | 
			
		||||
     inkscape:cy="8.9111233"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title />
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="M 12.5 3 A 9.5 9.4999914 0 0 0 3 12.5 A 9.5 9.4999914 0 0 0 12.5 22 A 9.5 9.4999914 0 0 0 22 12.5 A 9.5 9.4999914 0 0 0 12.5 3 z M 12.5 5 A 1.5 1.5000087 0 0 1 14 6.5 A 1.5 1.5000087 0 0 1 12.5 8 A 1.5 1.5000087 0 0 1 11 6.5 A 1.5 1.5000087 0 0 1 12.5 5 z M 10.521484 8.9785156 L 12.521484 8.9785156 A 1.50015 1.50015 0 0 1 14.021484 10.478516 L 14.021484 15.972656 A 1.50015 1.50015 0 0 1 14.498047 18.894531 C 14.498047 18.894531 13.74301 19.228309 12.789062 18.912109 C 12.312092 18.754109 11.776235 18.366625 11.458984 17.828125 C 11.141734 17.289525 11.021484 16.668469 11.021484 15.980469 L 11.021484 11.980469 L 10.521484 11.980469 A 1.50015 1.50015 0 1 1 10.521484 8.9804688 L 10.521484 8.9785156 z "
 | 
			
		||||
       transform="translate(0,1027.3622)"
 | 
			
		||||
       id="path4136" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.1 KiB  | 
							
								
								
									
										88
									
								
								VM/novnc/app/images/keyboard.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,88 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="keyboard.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/keyboard.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#717171"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="31.285341"
 | 
			
		||||
     inkscape:cy="8.8028469"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:snap-bbox-midpoints="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-midpoints="true"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title />
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
       d="M 7,3 C 4.8012876,3 3,4.8013 3,7 3,11.166667 3,15.333333 3,19.5 3,20.8764 4.1236413,22 5.5,22 l 14,0 C 20.876358,22 22,20.8764 22,19.5 22,15.333333 22,11.166667 22,7 22,4.8013 20.198712,3 18,3 Z m 0,2 11,0 c 1.125307,0 2,0.8747 2,2 L 20,12 5,12 5,7 C 5,5.8747 5.8746931,5 7,5 Z M 6.5,14 C 6.777,14 7,14.223 7,14.5 7,14.777 6.777,15 6.5,15 6.223,15 6,14.777 6,14.5 6,14.223 6.223,14 6.5,14 Z m 2,0 C 8.777,14 9,14.223 9,14.5 9,14.777 8.777,15 8.5,15 8.223,15 8,14.777 8,14.5 8,14.223 8.223,14 8.5,14 Z m 2,0 C 10.777,14 11,14.223 11,14.5 11,14.777 10.777,15 10.5,15 10.223,15 10,14.777 10,14.5 10,14.223 10.223,14 10.5,14 Z m 2,0 C 12.777,14 13,14.223 13,14.5 13,14.777 12.777,15 12.5,15 12.223,15 12,14.777 12,14.5 12,14.223 12.223,14 12.5,14 Z m 2,0 C 14.777,14 15,14.223 15,14.5 15,14.777 14.777,15 14.5,15 14.223,15 14,14.777 14,14.5 14,14.223 14.223,14 14.5,14 Z m 2,0 C 16.777,14 17,14.223 17,14.5 17,14.777 16.777,15 16.5,15 16.223,15 16,14.777 16,14.5 16,14.223 16.223,14 16.5,14 Z m 2,0 C 18.777,14 19,14.223 19,14.5 19,14.777 18.777,15 18.5,15 18.223,15 18,14.777 18,14.5 18,14.223 18.223,14 18.5,14 Z m -13,2 C 5.777,16 6,16.223 6,16.5 6,16.777 5.777,17 5.5,17 5.223,17 5,16.777 5,16.5 5,16.223 5.223,16 5.5,16 Z m 2,0 C 7.777,16 8,16.223 8,16.5 8,16.777 7.777,17 7.5,17 7.223,17 7,16.777 7,16.5 7,16.223 7.223,16 7.5,16 Z m 2,0 C 9.777,16 10,16.223 10,16.5 10,16.777 9.777,17 9.5,17 9.223,17 9,16.777 9,16.5 9,16.223 9.223,16 9.5,16 Z m 2,0 C 11.777,16 12,16.223 12,16.5 12,16.777 11.777,17 11.5,17 11.223,17 11,16.777 11,16.5 11,16.223 11.223,16 11.5,16 Z m 2,0 C 13.777,16 14,16.223 14,16.5 14,16.777 13.777,17 13.5,17 13.223,17 13,16.777 13,16.5 13,16.223 13.223,16 13.5,16 Z m 2,0 C 15.777,16 16,16.223 16,16.5 16,16.777 15.777,17 15.5,17 15.223,17 15,16.777 15,16.5 15,16.223 15.223,16 15.5,16 Z m 2,0 C 17.777,16 18,16.223 18,16.5 18,16.777 17.777,17 17.5,17 17.223,17 17,16.777 17,16.5 17,16.223 17.223,16 17.5,16 Z m 2,0 C 19.777,16 20,16.223 20,16.5 20,16.777 19.777,17 19.5,17 19.223,17 19,16.777 19,16.5 19,16.223 19.223,16 19.5,16 Z M 6,18 c 0.554,0 1,0.446 1,1 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 0,-0.554 0.446,-1 1,-1 z m 2.8261719,0 7.3476561,0 C 16.631643,18 17,18.368372 17,18.826172 l 0,0.347656 C 17,19.631628 16.631643,20 16.173828,20 L 8.8261719,20 C 8.3683573,20 8,19.631628 8,19.173828 L 8,18.826172 C 8,18.368372 8.3683573,18 8.8261719,18 Z m 10.1113281,0 0.125,0 C 19.581551,18 20,18.4184 20,18.9375 l 0,0.125 C 20,19.5816 19.581551,20 19.0625,20 l -0.125,0 C 18.418449,20 18,19.5816 18,19.0625 l 0,-0.125 C 18,18.4184 18.418449,18 18.9375,18 Z"
 | 
			
		||||
       transform="translate(0,1027.3622)"
 | 
			
		||||
       id="rect4160"
 | 
			
		||||
       inkscape:connector-curvature="0"
 | 
			
		||||
       sodipodi:nodetypes="sccssccsssssccssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
 | 
			
		||||
       d="m 12.499929,1033.8622 -2,2 1.500071,0 0,2 1,0 0,-2 1.499929,0 z"
 | 
			
		||||
       id="path4150"
 | 
			
		||||
       inkscape:connector-curvature="0"
 | 
			
		||||
       sodipodi:nodetypes="cccccccc" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 6.3 KiB  | 
							
								
								
									
										87
									
								
								VM/novnc/app/images/power.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,87 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="power.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="9.3159849"
 | 
			
		||||
     inkscape:cy="13.436208"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
       d="M 9 6.8183594 C 6.3418164 8.1213032 4.5 10.849161 4.5 14 C 4.5 18.4065 8.0935666 22 12.5 22 C 16.906433 22 20.5 18.4065 20.5 14 C 20.5 10.849161 18.658184 8.1213032 16 6.8183594 L 16 9.125 C 17.514327 10.211757 18.5 11.984508 18.5 14 C 18.5 17.3256 15.825553 20 12.5 20 C 9.1744469 20 6.5 17.3256 6.5 14 C 6.5 11.984508 7.4856727 10.211757 9 9.125 L 9 6.8183594 z "
 | 
			
		||||
       transform="translate(0,1027.3622)"
 | 
			
		||||
       id="path6140" />
 | 
			
		||||
    <path
 | 
			
		||||
       style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 | 
			
		||||
       d="m 12.5,1031.8836 0,6.4786"
 | 
			
		||||
       id="path6142"
 | 
			
		||||
       inkscape:connector-curvature="0"
 | 
			
		||||
       sodipodi:nodetypes="cc" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										76
									
								
								VM/novnc/app/images/settings.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,76 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="settings.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="22.627417"
 | 
			
		||||
     inkscape:cx="14.69683"
 | 
			
		||||
     inkscape:cy="8.8039511"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="M 11 3 L 11 5.1601562 A 7.5 7.5 0 0 0 8.3671875 6.2460938 L 6.84375 4.7226562 L 4.7226562 6.84375 L 6.2480469 8.3691406 A 7.5 7.5 0 0 0 5.1523438 11 L 3 11 L 3 14 L 5.1601562 14 A 7.5 7.5 0 0 0 6.2460938 16.632812 L 4.7226562 18.15625 L 6.84375 20.277344 L 8.3691406 18.751953 A 7.5 7.5 0 0 0 11 19.847656 L 11 22 L 14 22 L 14 19.839844 A 7.5 7.5 0 0 0 16.632812 18.753906 L 18.15625 20.277344 L 20.277344 18.15625 L 18.751953 16.630859 A 7.5 7.5 0 0 0 19.847656 14 L 22 14 L 22 11 L 19.839844 11 A 7.5 7.5 0 0 0 18.753906 8.3671875 L 20.277344 6.84375 L 18.15625 4.7226562 L 16.630859 6.2480469 A 7.5 7.5 0 0 0 14 5.1523438 L 14 3 L 11 3 z M 12.5 10 A 2.5 2.5 0 0 1 15 12.5 A 2.5 2.5 0 0 1 12.5 15 A 2.5 2.5 0 0 1 10 12.5 A 2.5 2.5 0 0 1 12.5 10 z "
 | 
			
		||||
       transform="translate(0,1027.3622)"
 | 
			
		||||
       id="rect4967" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.0 KiB  | 
							
								
								
									
										86
									
								
								VM/novnc/app/images/tab.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,86 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="tab.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="16"
 | 
			
		||||
     inkscape:cx="11.67335"
 | 
			
		||||
     inkscape:cy="17.881696"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       d="m 3,1031.3622 0,8 2,0 0,-4 0,-4 -2,0 z m 2,4 4,4 0,-3 13,0 0,-2 -13,0 0,-3 -4,4 z"
 | 
			
		||||
       id="rect5194"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
    <path
 | 
			
		||||
       id="path5211"
 | 
			
		||||
       d="m 22,1048.3622 0,-8 -2,0 0,4 0,4 2,0 z m -2,-4 -4,-4 0,3 -13,0 0,2 13,0 0,3 4,-4 z"
 | 
			
		||||
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
 | 
			
		||||
       inkscape:connector-curvature="0" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.9 KiB  | 
							
								
								
									
										90
									
								
								VM/novnc/app/images/toggleextrakeys.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,90 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="extrakeys.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="15.234555"
 | 
			
		||||
     inkscape:cy="9.9710826"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="false">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
       d="m 8,1031.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,8.9996 c 0,2.1987 1.8012876,4 4,4 l 9,0 c 2.198712,0 4,-1.8013 4,-4 l 0,-8.9996 c 0,-2.1987 -1.801288,-4 -4,-4 z m 0,2 9,0 c 1.125307,0 2,0.8747 2,2 l 0,7.0005 c 0,1.1253 -0.874693,2 -2,2 l -9,0 c -1.1253069,0 -2,-0.8747 -2,-2 l 0,-7.0005 c 0,-1.1253 0.8746931,-2 2,-2 z"
 | 
			
		||||
       id="rect5006"
 | 
			
		||||
       inkscape:connector-curvature="0"
 | 
			
		||||
       sodipodi:nodetypes="ssssssssssssssssss" />
 | 
			
		||||
    <g
 | 
			
		||||
       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
       id="text4167"
 | 
			
		||||
       transform="matrix(0.96021948,0,0,0.96021948,0.18921715,41.80659)">
 | 
			
		||||
      <path
 | 
			
		||||
         d="m 14.292969,1040.6791 -2.939453,0 -0.463868,1.3281 -1.889648,0 2.700195,-7.29 2.241211,0 2.700196,7.29 -1.889649,0 -0.458984,-1.3281 z m -2.470703,-1.3526 1.99707,0 -0.996094,-2.9004 -1.000976,2.9004 z"
 | 
			
		||||
         id="path4172"
 | 
			
		||||
         inkscape:connector-curvature="0" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
							
								
								
									
										81
									
								
								VM/novnc/app/images/warning.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,81 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"
 | 
			
		||||
   viewBox="0 0 25 25"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.91 r13725"
 | 
			
		||||
   sodipodi:docname="warning.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   inkscape:export-ydpi="90">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#959595"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="16.457343"
 | 
			
		||||
     inkscape:cy="12.179552"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-paths="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     showguides="false"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1136"
 | 
			
		||||
     inkscape:window-x="1920"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:object-nodes="true"
 | 
			
		||||
     inkscape:snap-intersection-paths="true"
 | 
			
		||||
     inkscape:snap-nodes="true"
 | 
			
		||||
     inkscape:snap-global="true">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4136" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(0,-1027.3622)">
 | 
			
		||||
    <path
 | 
			
		||||
       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
       d="M 12.513672 3.0019531 C 11.751609 2.9919531 11.052563 3.4242687 10.710938 4.1054688 L 3.2109375 19.105469 C 2.5461937 20.435369 3.5132277 21.9999 5 22 L 20 22 C 21.486772 21.9999 22.453806 20.435369 21.789062 19.105469 L 14.289062 4.1054688 C 13.951849 3.4330688 13.265888 3.0066531 12.513672 3.0019531 z M 12.478516 6.9804688 A 1.50015 1.50015 0 0 1 14 8.5 L 14 14.5 A 1.50015 1.50015 0 1 1 11 14.5 L 11 8.5 A 1.50015 1.50015 0 0 1 12.478516 6.9804688 z M 12.5 17 A 1.5 1.5 0 0 1 14 18.5 A 1.5 1.5 0 0 1 12.5 20 A 1.5 1.5 0 0 1 11 18.5 A 1.5 1.5 0 0 1 12.5 17 z "
 | 
			
		||||
       transform="translate(0,1027.3622)"
 | 
			
		||||
       id="path4208" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 3.8 KiB  | 
							
								
								
									
										65
									
								
								VM/novnc/app/images/windows.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,65 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   inkscape:export-ydpi="90"
 | 
			
		||||
   inkscape:export-xdpi="90"
 | 
			
		||||
   sodipodi:docname="windows.svg"
 | 
			
		||||
   inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
 | 
			
		||||
   inkscape:version="0.92.4 (unknown)"
 | 
			
		||||
   x="0px"
 | 
			
		||||
   y="0px"
 | 
			
		||||
   viewBox="-293 384 25 25"
 | 
			
		||||
   xml:space="preserve"
 | 
			
		||||
   width="25"
 | 
			
		||||
   height="25"><metadata
 | 
			
		||||
   id="metadata21"><rdf:RDF><cc:Work
 | 
			
		||||
       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
 | 
			
		||||
         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
 | 
			
		||||
   id="defs19" /><sodipodi:namedview
 | 
			
		||||
   pagecolor="#959595"
 | 
			
		||||
   bordercolor="#666666"
 | 
			
		||||
   borderopacity="1"
 | 
			
		||||
   objecttolerance="10"
 | 
			
		||||
   gridtolerance="10"
 | 
			
		||||
   guidetolerance="10"
 | 
			
		||||
   inkscape:pageopacity="0"
 | 
			
		||||
   inkscape:pageshadow="2"
 | 
			
		||||
   inkscape:window-width="1920"
 | 
			
		||||
   inkscape:window-height="1136"
 | 
			
		||||
   id="namedview17"
 | 
			
		||||
   showgrid="true"
 | 
			
		||||
   inkscape:pagecheckerboard="false"
 | 
			
		||||
   inkscape:zoom="32"
 | 
			
		||||
   inkscape:cx="3.926913"
 | 
			
		||||
   inkscape:cy="13.255959"
 | 
			
		||||
   inkscape:window-x="1920"
 | 
			
		||||
   inkscape:window-y="27"
 | 
			
		||||
   inkscape:window-maximized="1"
 | 
			
		||||
   inkscape:current-layer="svg2"><inkscape:grid
 | 
			
		||||
     type="xygrid"
 | 
			
		||||
     id="grid818" /></sodipodi:namedview>
 | 
			
		||||
<style
 | 
			
		||||
   type="text/css"
 | 
			
		||||
   id="style2">
 | 
			
		||||
	.st0{fill:#FFFFFF;}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<path
 | 
			
		||||
   style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
 | 
			
		||||
   d="M 21 4 L 11 5.1757812 L 11 12 L 21 12 L 21 4 z M 10 5.2949219 L 4 6 L 4 12 L 10 12 L 10 5.2949219 z "
 | 
			
		||||
   transform="translate(-293,384)"
 | 
			
		||||
   id="path853" /><path
 | 
			
		||||
   id="path858"
 | 
			
		||||
   d="m -272,405 -10,-1.17578 V 397 h 10 z M -283,403.70508 -289,403 v -6 h 6 z"
 | 
			
		||||
   style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
   inkscape:connector-curvature="0" /></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.4 KiB  | 
							
								
								
									
										1
									
								
								VM/novnc/app/locale/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
DO NOT MODIFY THE FILES IN THIS FOLDER, THEY ARE AUTOMATICALLY GENERATED FROM THE PO-FILES.
 | 
			
		||||
							
								
								
									
										71
									
								
								VM/novnc/app/locale/cs.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,71 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Připojení...",
 | 
			
		||||
    "Disconnecting...": "Odpojení...",
 | 
			
		||||
    "Reconnecting...": "Obnova připojení...",
 | 
			
		||||
    "Internal error": "Vnitřní chyba",
 | 
			
		||||
    "Must set host": "Hostitel musí být nastavení",
 | 
			
		||||
    "Connected (encrypted) to ": "Připojení (šifrované) k ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Připojení (nešifrované) k ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Něco se pokazilo, odpojeno",
 | 
			
		||||
    "Failed to connect to server": "Chyba připojení k serveru",
 | 
			
		||||
    "Disconnected": "Odpojeno",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Nové připojení bylo odmítnuto s odůvodněním: ",
 | 
			
		||||
    "New connection has been rejected": "Nové připojení bylo odmítnuto",
 | 
			
		||||
    "Password is required": "Je vyžadováno heslo",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC narazilo na chybu:",
 | 
			
		||||
    "Hide/Show the control bar": "Skrýt/zobrazit ovládací panel",
 | 
			
		||||
    "Move/Drag Viewport": "Přesunout/přetáhnout výřez",
 | 
			
		||||
    "viewport drag": "přesun výřezu",
 | 
			
		||||
    "Active Mouse Button": "Aktivní tlačítka myši",
 | 
			
		||||
    "No mousebutton": "Žádné",
 | 
			
		||||
    "Left mousebutton": "Levé tlačítko myši",
 | 
			
		||||
    "Middle mousebutton": "Prostřední tlačítko myši",
 | 
			
		||||
    "Right mousebutton": "Pravé tlačítko myši",
 | 
			
		||||
    "Keyboard": "Klávesnice",
 | 
			
		||||
    "Show Keyboard": "Zobrazit klávesnici",
 | 
			
		||||
    "Extra keys": "Extra klávesy",
 | 
			
		||||
    "Show Extra Keys": "Zobrazit extra klávesy",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Přepnout Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Přepnout Alt",
 | 
			
		||||
    "Send Tab": "Odeslat tabulátor",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Odeslat Esc",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Poslat Ctrl-Alt-Del",
 | 
			
		||||
    "Shutdown/Reboot": "Vypnutí/Restart",
 | 
			
		||||
    "Shutdown/Reboot...": "Vypnutí/Restart...",
 | 
			
		||||
    "Power": "Napájení",
 | 
			
		||||
    "Shutdown": "Vypnout",
 | 
			
		||||
    "Reboot": "Restart",
 | 
			
		||||
    "Reset": "Reset",
 | 
			
		||||
    "Clipboard": "Schránka",
 | 
			
		||||
    "Clear": "Vymazat",
 | 
			
		||||
    "Fullscreen": "Celá obrazovka",
 | 
			
		||||
    "Settings": "Nastavení",
 | 
			
		||||
    "Shared Mode": "Sdílený režim",
 | 
			
		||||
    "View Only": "Pouze prohlížení",
 | 
			
		||||
    "Clip to Window": "Přizpůsobit oknu",
 | 
			
		||||
    "Scaling Mode:": "Přizpůsobení velikosti",
 | 
			
		||||
    "None": "Žádné",
 | 
			
		||||
    "Local Scaling": "Místní",
 | 
			
		||||
    "Remote Resizing": "Vzdálené",
 | 
			
		||||
    "Advanced": "Pokročilé",
 | 
			
		||||
    "Repeater ID:": "ID opakovače",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Šifrování:",
 | 
			
		||||
    "Host:": "Hostitel:",
 | 
			
		||||
    "Port:": "Port:",
 | 
			
		||||
    "Path:": "Cesta",
 | 
			
		||||
    "Automatic Reconnect": "Automatická obnova připojení",
 | 
			
		||||
    "Reconnect Delay (ms):": "Zpoždění připojení (ms)",
 | 
			
		||||
    "Show Dot when No Cursor": "Tečka místo chybějícího kurzoru myši",
 | 
			
		||||
    "Logging:": "Logování:",
 | 
			
		||||
    "Disconnect": "Odpojit",
 | 
			
		||||
    "Connect": "Připojit",
 | 
			
		||||
    "Password:": "Heslo",
 | 
			
		||||
    "Send Password": "Odeslat heslo",
 | 
			
		||||
    "Cancel": "Zrušit"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								VM/novnc/app/locale/de.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,69 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Verbinden...",
 | 
			
		||||
    "Disconnecting...": "Verbindung trennen...",
 | 
			
		||||
    "Reconnecting...": "Verbindung wiederherstellen...",
 | 
			
		||||
    "Internal error": "Interner Fehler",
 | 
			
		||||
    "Must set host": "Richten Sie den Server ein",
 | 
			
		||||
    "Connected (encrypted) to ": "Verbunden mit (verschlüsselt) ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Verbunden mit (unverschlüsselt) ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Etwas lief schief, Verbindung wurde getrennt",
 | 
			
		||||
    "Disconnected": "Verbindung zum Server getrennt",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Verbindung wurde aus folgendem Grund abgelehnt: ",
 | 
			
		||||
    "New connection has been rejected": "Verbindung wurde abgelehnt",
 | 
			
		||||
    "Password is required": "Passwort ist erforderlich",
 | 
			
		||||
    "noVNC encountered an error:": "Ein Fehler ist aufgetreten:",
 | 
			
		||||
    "Hide/Show the control bar": "Kontrollleiste verstecken/anzeigen",
 | 
			
		||||
    "Move/Drag Viewport": "Ansichtsfenster verschieben/ziehen",
 | 
			
		||||
    "viewport drag": "Ansichtsfenster ziehen",
 | 
			
		||||
    "Active Mouse Button": "Aktive Maustaste",
 | 
			
		||||
    "No mousebutton": "Keine Maustaste",
 | 
			
		||||
    "Left mousebutton": "Linke Maustaste",
 | 
			
		||||
    "Middle mousebutton": "Mittlere Maustaste",
 | 
			
		||||
    "Right mousebutton": "Rechte Maustaste",
 | 
			
		||||
    "Keyboard": "Tastatur",
 | 
			
		||||
    "Show Keyboard": "Tastatur anzeigen",
 | 
			
		||||
    "Extra keys": "Zusatztasten",
 | 
			
		||||
    "Show Extra Keys": "Zusatztasten anzeigen",
 | 
			
		||||
    "Ctrl": "Strg",
 | 
			
		||||
    "Toggle Ctrl": "Strg umschalten",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Alt umschalten",
 | 
			
		||||
    "Send Tab": "Tab senden",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Escape senden",
 | 
			
		||||
    "Ctrl+Alt+Del": "Strg+Alt+Entf",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Strg+Alt+Entf senden",
 | 
			
		||||
    "Shutdown/Reboot": "Herunterfahren/Neustarten",
 | 
			
		||||
    "Shutdown/Reboot...": "Herunterfahren/Neustarten...",
 | 
			
		||||
    "Power": "Energie",
 | 
			
		||||
    "Shutdown": "Herunterfahren",
 | 
			
		||||
    "Reboot": "Neustarten",
 | 
			
		||||
    "Reset": "Zurücksetzen",
 | 
			
		||||
    "Clipboard": "Zwischenablage",
 | 
			
		||||
    "Clear": "Löschen",
 | 
			
		||||
    "Fullscreen": "Vollbild",
 | 
			
		||||
    "Settings": "Einstellungen",
 | 
			
		||||
    "Shared Mode": "Geteilter Modus",
 | 
			
		||||
    "View Only": "Nur betrachten",
 | 
			
		||||
    "Clip to Window": "Auf Fenster begrenzen",
 | 
			
		||||
    "Scaling Mode:": "Skalierungsmodus:",
 | 
			
		||||
    "None": "Keiner",
 | 
			
		||||
    "Local Scaling": "Lokales skalieren",
 | 
			
		||||
    "Remote Resizing": "Serverseitiges skalieren",
 | 
			
		||||
    "Advanced": "Erweitert",
 | 
			
		||||
    "Repeater ID:": "Repeater ID:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Verschlüsselt",
 | 
			
		||||
    "Host:": "Server:",
 | 
			
		||||
    "Port:": "Port:",
 | 
			
		||||
    "Path:": "Pfad:",
 | 
			
		||||
    "Automatic Reconnect": "Automatisch wiederverbinden",
 | 
			
		||||
    "Reconnect Delay (ms):": "Wiederverbindungsverzögerung (ms):",
 | 
			
		||||
    "Logging:": "Protokollierung:",
 | 
			
		||||
    "Disconnect": "Verbindung trennen",
 | 
			
		||||
    "Connect": "Verbinden",
 | 
			
		||||
    "Password:": "Passwort:",
 | 
			
		||||
    "Cancel": "Abbrechen",
 | 
			
		||||
    "Canvas not supported.": "Canvas nicht unterstützt."
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								VM/novnc/app/locale/el.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,79 @@
 | 
			
		||||
{
 | 
			
		||||
    "HTTPS is required for full functionality": "Το HTTPS είναι απαιτούμενο για πλήρη λειτουργικότητα",
 | 
			
		||||
    "Connecting...": "Συνδέεται...",
 | 
			
		||||
    "Disconnecting...": "Aποσυνδέεται...",
 | 
			
		||||
    "Reconnecting...": "Επανασυνδέεται...",
 | 
			
		||||
    "Internal error": "Εσωτερικό σφάλμα",
 | 
			
		||||
    "Must set host": "Πρέπει να οριστεί ο διακομιστής",
 | 
			
		||||
    "Connected (encrypted) to ": "Συνδέθηκε (κρυπτογραφημένα) με το ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Συνδέθηκε (μη κρυπτογραφημένα) με το ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Κάτι πήγε στραβά, η σύνδεση διακόπηκε",
 | 
			
		||||
    "Failed to connect to server": "Αποτυχία στη σύνδεση με το διακομιστή",
 | 
			
		||||
    "Disconnected": "Αποσυνδέθηκε",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Η νέα σύνδεση απορρίφθηκε διότι: ",
 | 
			
		||||
    "New connection has been rejected": "Η νέα σύνδεση απορρίφθηκε ",
 | 
			
		||||
    "Credentials are required": "Απαιτούνται διαπιστευτήρια",
 | 
			
		||||
    "noVNC encountered an error:": "το noVNC αντιμετώπισε ένα σφάλμα:",
 | 
			
		||||
    "Hide/Show the control bar": "Απόκρυψη/Εμφάνιση γραμμής ελέγχου",
 | 
			
		||||
    "Drag": "Σύρσιμο",
 | 
			
		||||
    "Move/Drag Viewport": "Μετακίνηση/Σύρσιμο Θεατού πεδίου",
 | 
			
		||||
    "Keyboard": "Πληκτρολόγιο",
 | 
			
		||||
    "Show Keyboard": "Εμφάνιση Πληκτρολογίου",
 | 
			
		||||
    "Extra keys": "Επιπλέον πλήκτρα",
 | 
			
		||||
    "Show Extra Keys": "Εμφάνιση Επιπλέον Πλήκτρων",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Εναλλαγή Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Εναλλαγή Alt",
 | 
			
		||||
    "Toggle Windows": "Εναλλαγή Παράθυρων",
 | 
			
		||||
    "Windows": "Παράθυρα",
 | 
			
		||||
    "Send Tab": "Αποστολή Tab",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Αποστολή Escape",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Αποστολή Ctrl-Alt-Del",
 | 
			
		||||
    "Shutdown/Reboot": "Κλείσιμο/Επανεκκίνηση",
 | 
			
		||||
    "Shutdown/Reboot...": "Κλείσιμο/Επανεκκίνηση...",
 | 
			
		||||
    "Power": "Απενεργοποίηση",
 | 
			
		||||
    "Shutdown": "Κλείσιμο",
 | 
			
		||||
    "Reboot": "Επανεκκίνηση",
 | 
			
		||||
    "Reset": "Επαναφορά",
 | 
			
		||||
    "Clipboard": "Πρόχειρο",
 | 
			
		||||
    "Edit clipboard content in the textarea below.": "Επεξεργαστείτε το περιεχόμενο του πρόχειρου στην περιοχή κειμένου παρακάτω.",
 | 
			
		||||
    "Settings": "Ρυθμίσεις",
 | 
			
		||||
    "Shared Mode": "Κοινόχρηστη Λειτουργία",
 | 
			
		||||
    "View Only": "Μόνο Θέαση",
 | 
			
		||||
    "Clip to Window": "Αποκοπή στο όριο του Παράθυρου",
 | 
			
		||||
    "Scaling Mode:": "Λειτουργία Κλιμάκωσης:",
 | 
			
		||||
    "None": "Καμία",
 | 
			
		||||
    "Local Scaling": "Τοπική Κλιμάκωση",
 | 
			
		||||
    "Remote Resizing": "Απομακρυσμένη Αλλαγή μεγέθους",
 | 
			
		||||
    "Advanced": "Για προχωρημένους",
 | 
			
		||||
    "Quality:": "Ποιότητα:",
 | 
			
		||||
    "Compression level:": "Επίπεδο συμπίεσης:",
 | 
			
		||||
    "Repeater ID:": "Repeater ID:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Κρυπτογράφηση",
 | 
			
		||||
    "Host:": "Όνομα διακομιστή:",
 | 
			
		||||
    "Port:": "Πόρτα διακομιστή:",
 | 
			
		||||
    "Path:": "Διαδρομή:",
 | 
			
		||||
    "Automatic Reconnect": "Αυτόματη επανασύνδεση",
 | 
			
		||||
    "Reconnect Delay (ms):": "Καθυστέρηση επανασύνδεσης (ms):",
 | 
			
		||||
    "Show Dot when No Cursor": "Εμφάνιση Τελείας όταν δεν υπάρχει Δρομέας",
 | 
			
		||||
    "Logging:": "Καταγραφή:",
 | 
			
		||||
    "Version:": "Έκδοση:",
 | 
			
		||||
    "Disconnect": "Αποσύνδεση",
 | 
			
		||||
    "Connect": "Σύνδεση",
 | 
			
		||||
    "Server identity": "Ταυτότητα Διακομιστή",
 | 
			
		||||
    "The server has provided the following identifying information:": "Ο διακομιστής παρείχε την ακόλουθη πληροφορία ταυτοποίησης:",
 | 
			
		||||
    "Fingerprint:": "Δακτυλικό αποτύπωμα:",
 | 
			
		||||
    "Please verify that the information is correct and press \"Approve\". Otherwise press \"Reject\".": "Παρακαλώ επαληθεύσετε ότι η πληροφορία είναι σωστή και πιέστε \"Αποδοχή\". Αλλιώς πιέστε \"Απόρριψη\".",
 | 
			
		||||
    "Approve": "Αποδοχή",
 | 
			
		||||
    "Reject": "Απόρριψη",
 | 
			
		||||
    "Credentials": "Διαπιστευτήρια",
 | 
			
		||||
    "Username:": "Κωδικός Χρήστη:",
 | 
			
		||||
    "Password:": "Κωδικός Πρόσβασης:",
 | 
			
		||||
    "Send Credentials": "Αποστολή Διαπιστευτηρίων",
 | 
			
		||||
    "Cancel": "Ακύρωση"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								VM/novnc/app/locale/es.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,68 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Conectando...",
 | 
			
		||||
    "Connected (encrypted) to ": "Conectado (con encriptación) a",
 | 
			
		||||
    "Connected (unencrypted) to ": "Conectado (sin encriptación) a",
 | 
			
		||||
    "Disconnecting...": "Desconectando...",
 | 
			
		||||
    "Disconnected": "Desconectado",
 | 
			
		||||
    "Must set host": "Se debe configurar el host",
 | 
			
		||||
    "Reconnecting...": "Reconectando...",
 | 
			
		||||
    "Password is required": "La contraseña es obligatoria",
 | 
			
		||||
    "Disconnect timeout": "Tiempo de desconexión agotado",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC ha encontrado un error:",
 | 
			
		||||
    "Hide/Show the control bar": "Ocultar/Mostrar la barra de control",
 | 
			
		||||
    "Move/Drag Viewport": "Mover/Arrastrar la ventana",
 | 
			
		||||
    "viewport drag": "Arrastrar la ventana",
 | 
			
		||||
    "Active Mouse Button": "Botón activo del ratón",
 | 
			
		||||
    "No mousebutton": "Ningún botón del ratón",
 | 
			
		||||
    "Left mousebutton": "Botón izquierdo del ratón",
 | 
			
		||||
    "Middle mousebutton": "Botón central del ratón",
 | 
			
		||||
    "Right mousebutton": "Botón derecho del ratón",
 | 
			
		||||
    "Keyboard": "Teclado",
 | 
			
		||||
    "Show Keyboard": "Mostrar teclado",
 | 
			
		||||
    "Extra keys": "Teclas adicionales",
 | 
			
		||||
    "Show Extra Keys": "Mostrar Teclas Adicionales",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Pulsar/Soltar Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Pulsar/Soltar Alt",
 | 
			
		||||
    "Send Tab": "Enviar Tabulación",
 | 
			
		||||
    "Tab": "Tabulación",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Enviar Escape",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Enviar Ctrl+Alt+Del",
 | 
			
		||||
    "Shutdown/Reboot": "Apagar/Reiniciar",
 | 
			
		||||
    "Shutdown/Reboot...": "Apagar/Reiniciar...",
 | 
			
		||||
    "Power": "Encender",
 | 
			
		||||
    "Shutdown": "Apagar",
 | 
			
		||||
    "Reboot": "Reiniciar",
 | 
			
		||||
    "Reset": "Restablecer",
 | 
			
		||||
    "Clipboard": "Portapapeles",
 | 
			
		||||
    "Clear": "Vaciar",
 | 
			
		||||
    "Fullscreen": "Pantalla Completa",
 | 
			
		||||
    "Settings": "Configuraciones",
 | 
			
		||||
    "Encrypt": "Encriptar",
 | 
			
		||||
    "Shared Mode": "Modo Compartido",
 | 
			
		||||
    "View Only": "Solo visualización",
 | 
			
		||||
    "Clip to Window": "Recortar al tamaño de la ventana",
 | 
			
		||||
    "Scaling Mode:": "Modo de escalado:",
 | 
			
		||||
    "None": "Ninguno",
 | 
			
		||||
    "Local Scaling": "Escalado Local",
 | 
			
		||||
    "Local Downscaling": "Reducción de escala local",
 | 
			
		||||
    "Remote Resizing": "Cambio de tamaño remoto",
 | 
			
		||||
    "Advanced": "Avanzado",
 | 
			
		||||
    "Local Cursor": "Cursor Local",
 | 
			
		||||
    "Repeater ID:": "ID del Repetidor:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Host:": "Host:",
 | 
			
		||||
    "Port:": "Puerto:",
 | 
			
		||||
    "Path:": "Ruta:",
 | 
			
		||||
    "Automatic Reconnect": "Reconexión automática",
 | 
			
		||||
    "Reconnect Delay (ms):": "Retraso en la reconexión (ms):",
 | 
			
		||||
    "Logging:": "Registrando:",
 | 
			
		||||
    "Disconnect": "Desconectar",
 | 
			
		||||
    "Connect": "Conectar",
 | 
			
		||||
    "Password:": "Contraseña:",
 | 
			
		||||
    "Cancel": "Cancelar",
 | 
			
		||||
    "Canvas not supported.": "Canvas no soportado."
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								VM/novnc/app/locale/fr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,72 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "En cours de connexion...",
 | 
			
		||||
    "Disconnecting...": "Déconnexion en cours...",
 | 
			
		||||
    "Reconnecting...": "Reconnexion en cours...",
 | 
			
		||||
    "Internal error": "Erreur interne",
 | 
			
		||||
    "Must set host": "Doit définir l'hôte",
 | 
			
		||||
    "Connected (encrypted) to ": "Connecté (chiffré) à ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Connecté (non chiffré) à ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Quelque chose s'est mal passé, la connexion a été fermée",
 | 
			
		||||
    "Failed to connect to server": "Échec de connexion au serveur",
 | 
			
		||||
    "Disconnected": "Déconnecté",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Une nouvelle connexion a été rejetée avec motif : ",
 | 
			
		||||
    "New connection has been rejected": "Une nouvelle connexion a été rejetée",
 | 
			
		||||
    "Credentials are required": "Les identifiants sont requis",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC a rencontré une erreur :",
 | 
			
		||||
    "Hide/Show the control bar": "Masquer/Afficher la barre de contrôle",
 | 
			
		||||
    "Drag": "Faire glisser",
 | 
			
		||||
    "Move/Drag Viewport": "Déplacer/faire glisser le Viewport",
 | 
			
		||||
    "Keyboard": "Clavier",
 | 
			
		||||
    "Show Keyboard": "Afficher le clavier",
 | 
			
		||||
    "Extra keys": "Touches supplémentaires",
 | 
			
		||||
    "Show Extra Keys": "Afficher les touches supplémentaires",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Basculer Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Basculer Alt",
 | 
			
		||||
    "Toggle Windows": "Basculer Windows",
 | 
			
		||||
    "Windows": "Windows",
 | 
			
		||||
    "Send Tab": "Envoyer l'onglet",
 | 
			
		||||
    "Tab": "l'onglet",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Envoyer Escape",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Envoyer Ctrl-Alt-Del",
 | 
			
		||||
    "Shutdown/Reboot": "Arrêter/Redémarrer",
 | 
			
		||||
    "Shutdown/Reboot...": "Arrêter/Redémarrer...",
 | 
			
		||||
    "Power": "Alimentation",
 | 
			
		||||
    "Shutdown": "Arrêter",
 | 
			
		||||
    "Reboot": "Redémarrer",
 | 
			
		||||
    "Reset": "Réinitialiser",
 | 
			
		||||
    "Clipboard": "Presse-papiers",
 | 
			
		||||
    "Clear": "Effacer",
 | 
			
		||||
    "Fullscreen": "Plein écran",
 | 
			
		||||
    "Settings": "Paramètres",
 | 
			
		||||
    "Shared Mode": "Mode partagé",
 | 
			
		||||
    "View Only": "Afficher uniquement",
 | 
			
		||||
    "Clip to Window": "Clip à fenêtre",
 | 
			
		||||
    "Scaling Mode:": "Mode mise à l'échelle :",
 | 
			
		||||
    "None": "Aucun",
 | 
			
		||||
    "Local Scaling": "Mise à l'échelle locale",
 | 
			
		||||
    "Remote Resizing": "Redimensionnement à distance",
 | 
			
		||||
    "Advanced": "Avancé",
 | 
			
		||||
    "Quality:": "Qualité :",
 | 
			
		||||
    "Compression level:": "Niveau de compression :",
 | 
			
		||||
    "Repeater ID:": "ID Répéteur :",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Chiffrer",
 | 
			
		||||
    "Host:": "Hôte :",
 | 
			
		||||
    "Port:": "Port :",
 | 
			
		||||
    "Path:": "Chemin :",
 | 
			
		||||
    "Automatic Reconnect": "Reconnecter automatiquemen",
 | 
			
		||||
    "Reconnect Delay (ms):": "Délai de reconnexion (ms) :",
 | 
			
		||||
    "Show Dot when No Cursor": "Afficher le point lorsqu'il n'y a pas de curseur",
 | 
			
		||||
    "Logging:": "Se connecter :",
 | 
			
		||||
    "Version:": "Version :",
 | 
			
		||||
    "Disconnect": "Déconnecter",
 | 
			
		||||
    "Connect": "Connecter",
 | 
			
		||||
    "Username:": "Nom d'utilisateur :",
 | 
			
		||||
    "Password:": "Mot de passe :",
 | 
			
		||||
    "Send Credentials": "Envoyer les identifiants",
 | 
			
		||||
    "Cancel": "Annuler"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								VM/novnc/app/locale/it.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,68 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Connessione in corso...",
 | 
			
		||||
    "Disconnecting...": "Disconnessione...",
 | 
			
		||||
    "Reconnecting...": "Riconnessione...",
 | 
			
		||||
    "Internal error": "Errore interno",
 | 
			
		||||
    "Must set host": "Devi impostare l'host",
 | 
			
		||||
    "Connected (encrypted) to ": "Connesso (crittografato) a ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Connesso (non crittografato) a",
 | 
			
		||||
    "Something went wrong, connection is closed": "Qualcosa è andato storto, la connessione è stata chiusa",
 | 
			
		||||
    "Failed to connect to server": "Impossibile connettersi al server",
 | 
			
		||||
    "Disconnected": "Disconnesso",
 | 
			
		||||
    "New connection has been rejected with reason: ": "La nuova connessione è stata rifiutata con motivo: ",
 | 
			
		||||
    "New connection has been rejected": "La nuova connessione è stata rifiutata",
 | 
			
		||||
    "Credentials are required": "Le credenziali sono obbligatorie",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC ha riscontrato un errore:",
 | 
			
		||||
    "Hide/Show the control bar": "Nascondi/Mostra la barra di controllo",
 | 
			
		||||
    "Keyboard": "Tastiera",
 | 
			
		||||
    "Show Keyboard": "Mostra tastiera",
 | 
			
		||||
    "Extra keys": "Tasti Aggiuntivi",
 | 
			
		||||
    "Show Extra Keys": "Mostra Tasti Aggiuntivi",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Tieni premuto Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Tieni premuto Alt",
 | 
			
		||||
    "Toggle Windows": "Tieni premuto Windows",
 | 
			
		||||
    "Windows": "Windows",
 | 
			
		||||
    "Send Tab": "Invia Tab",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Invia Esc",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Canc",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Invia Ctrl-Alt-Canc",
 | 
			
		||||
    "Shutdown/Reboot": "Spegnimento/Riavvio",
 | 
			
		||||
    "Shutdown/Reboot...": "Spegnimento/Riavvio...",
 | 
			
		||||
    "Power": "Alimentazione",
 | 
			
		||||
    "Shutdown": "Spegnimento",
 | 
			
		||||
    "Reboot": "Riavvio",
 | 
			
		||||
    "Reset": "Reset",
 | 
			
		||||
    "Clipboard": "Clipboard",
 | 
			
		||||
    "Clear": "Pulisci",
 | 
			
		||||
    "Fullscreen": "Schermo intero",
 | 
			
		||||
    "Settings": "Impostazioni",
 | 
			
		||||
    "Shared Mode": "Modalità condivisa",
 | 
			
		||||
    "View Only": "Sola Visualizzazione",
 | 
			
		||||
    "Scaling Mode:": "Modalità di ridimensionamento:",
 | 
			
		||||
    "None": "Nessuna",
 | 
			
		||||
    "Local Scaling": "Ridimensionamento Locale",
 | 
			
		||||
    "Remote Resizing": "Ridimensionamento Remoto",
 | 
			
		||||
    "Advanced": "Avanzate",
 | 
			
		||||
    "Quality:": "Qualità:",
 | 
			
		||||
    "Compression level:": "Livello Compressione:",
 | 
			
		||||
    "Repeater ID:": "ID Ripetitore:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Crittografa",
 | 
			
		||||
    "Host:": "Host:",
 | 
			
		||||
    "Port:": "Porta:",
 | 
			
		||||
    "Path:": "Percorso:",
 | 
			
		||||
    "Automatic Reconnect": "Riconnessione Automatica",
 | 
			
		||||
    "Reconnect Delay (ms):": "Ritardo Riconnessione (ms):",
 | 
			
		||||
    "Show Dot when No Cursor": "Mostra Punto quando Nessun Cursore",
 | 
			
		||||
    "Version:": "Versione:",
 | 
			
		||||
    "Disconnect": "Disconnetti",
 | 
			
		||||
    "Connect": "Connetti",
 | 
			
		||||
    "Username:": "Utente:",
 | 
			
		||||
    "Password:": "Password:",
 | 
			
		||||
    "Send Credentials": "Invia Credenziale",
 | 
			
		||||
    "Cancel": "Annulla"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								VM/novnc/app/locale/ja.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,80 @@
 | 
			
		||||
{
 | 
			
		||||
    "HTTPS is required for full functionality": "すべての機能を使用するにはHTTPS接続が必要です",
 | 
			
		||||
    "Connecting...": "接続しています...",
 | 
			
		||||
    "Disconnecting...": "切断しています...",
 | 
			
		||||
    "Reconnecting...": "再接続しています...",
 | 
			
		||||
    "Internal error": "内部エラー",
 | 
			
		||||
    "Must set host": "ホストを設定する必要があります",
 | 
			
		||||
    "Connected (encrypted) to ": "接続しました (暗号化済み): ",
 | 
			
		||||
    "Connected (unencrypted) to ": "接続しました (暗号化されていません): ",
 | 
			
		||||
    "Something went wrong, connection is closed": "何らかの問題で、接続が閉じられました",
 | 
			
		||||
    "Failed to connect to server": "サーバーへの接続に失敗しました",
 | 
			
		||||
    "Disconnected": "切断しました",
 | 
			
		||||
    "New connection has been rejected with reason: ": "新規接続は次の理由で拒否されました: ",
 | 
			
		||||
    "New connection has been rejected": "新規接続は拒否されました",
 | 
			
		||||
    "Credentials are required": "資格情報が必要です",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC でエラーが発生しました:",
 | 
			
		||||
    "Hide/Show the control bar": "コントロールバーを隠す/表示する",
 | 
			
		||||
    "Drag": "ドラッグ",
 | 
			
		||||
    "Move/Drag Viewport": "ビューポートを移動/ドラッグ",
 | 
			
		||||
    "Keyboard": "キーボード",
 | 
			
		||||
    "Show Keyboard": "キーボードを表示",
 | 
			
		||||
    "Extra keys": "追加キー",
 | 
			
		||||
    "Show Extra Keys": "追加キーを表示",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Ctrl キーをトグル",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Alt キーをトグル",
 | 
			
		||||
    "Toggle Windows": "Windows キーをトグル",
 | 
			
		||||
    "Windows": "Windows",
 | 
			
		||||
    "Send Tab": "Tab キーを送信",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Escape キーを送信",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Ctrl-Alt-Del を送信",
 | 
			
		||||
    "Shutdown/Reboot": "シャットダウン/再起動",
 | 
			
		||||
    "Shutdown/Reboot...": "シャットダウン/再起動...",
 | 
			
		||||
    "Power": "電源",
 | 
			
		||||
    "Shutdown": "シャットダウン",
 | 
			
		||||
    "Reboot": "再起動",
 | 
			
		||||
    "Reset": "リセット",
 | 
			
		||||
    "Clipboard": "クリップボード",
 | 
			
		||||
    "Edit clipboard content in the textarea below.": "以下の入力欄からクリップボードの内容を編集できます。",
 | 
			
		||||
    "Full Screen": "全画面表示",
 | 
			
		||||
    "Settings": "設定",
 | 
			
		||||
    "Shared Mode": "共有モード",
 | 
			
		||||
    "View Only": "表示専用",
 | 
			
		||||
    "Clip to Window": "ウィンドウにクリップ",
 | 
			
		||||
    "Scaling Mode:": "スケーリングモード:",
 | 
			
		||||
    "None": "なし",
 | 
			
		||||
    "Local Scaling": "ローカルスケーリング",
 | 
			
		||||
    "Remote Resizing": "リモートでリサイズ",
 | 
			
		||||
    "Advanced": "高度",
 | 
			
		||||
    "Quality:": "品質:",
 | 
			
		||||
    "Compression level:": "圧縮レベル:",
 | 
			
		||||
    "Repeater ID:": "リピーター ID:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "暗号化",
 | 
			
		||||
    "Host:": "ホスト:",
 | 
			
		||||
    "Port:": "ポート:",
 | 
			
		||||
    "Path:": "パス:",
 | 
			
		||||
    "Automatic Reconnect": "自動再接続",
 | 
			
		||||
    "Reconnect Delay (ms):": "再接続する遅延 (ミリ秒):",
 | 
			
		||||
    "Show Dot when No Cursor": "カーソルがないときにドットを表示する",
 | 
			
		||||
    "Logging:": "ロギング:",
 | 
			
		||||
    "Version:": "バージョン:",
 | 
			
		||||
    "Disconnect": "切断",
 | 
			
		||||
    "Connect": "接続",
 | 
			
		||||
    "Server identity": "サーバーの識別情報",
 | 
			
		||||
    "The server has provided the following identifying information:": "サーバーは以下の識別情報を提供しています:",
 | 
			
		||||
    "Fingerprint:": "フィンガープリント:",
 | 
			
		||||
    "Please verify that the information is correct and press \"Approve\". Otherwise press \"Reject\".": "この情報が正しい場合は「承認」を、そうでない場合は「拒否」を押してください。",
 | 
			
		||||
    "Approve": "承認",
 | 
			
		||||
    "Reject": "拒否",
 | 
			
		||||
    "Credentials": "資格情報",
 | 
			
		||||
    "Username:": "ユーザー名:",
 | 
			
		||||
    "Password:": "パスワード:",
 | 
			
		||||
    "Send Credentials": "資格情報を送信",
 | 
			
		||||
    "Cancel": "キャンセル"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								VM/novnc/app/locale/ko.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,70 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "연결중...",
 | 
			
		||||
    "Disconnecting...": "연결 해제중...",
 | 
			
		||||
    "Reconnecting...": "재연결중...",
 | 
			
		||||
    "Internal error": "내부 오류",
 | 
			
		||||
    "Must set host": "호스트는 설정되어야 합니다.",
 | 
			
		||||
    "Connected (encrypted) to ": "다음과 (암호화되어) 연결되었습니다:",
 | 
			
		||||
    "Connected (unencrypted) to ": "다음과 (암호화 없이) 연결되었습니다:",
 | 
			
		||||
    "Something went wrong, connection is closed": "무언가 잘못되었습니다, 연결이 닫혔습니다.",
 | 
			
		||||
    "Failed to connect to server": "서버에 연결하지 못했습니다.",
 | 
			
		||||
    "Disconnected": "연결이 해제되었습니다.",
 | 
			
		||||
    "New connection has been rejected with reason: ": "새 연결이 다음 이유로 거부되었습니다:",
 | 
			
		||||
    "New connection has been rejected": "새 연결이 거부되었습니다.",
 | 
			
		||||
    "Password is required": "비밀번호가 필요합니다.",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC에 오류가 발생했습니다:",
 | 
			
		||||
    "Hide/Show the control bar": "컨트롤 바 숨기기/보이기",
 | 
			
		||||
    "Move/Drag Viewport": "움직이기/드래그 뷰포트",
 | 
			
		||||
    "viewport drag": "뷰포트 드래그",
 | 
			
		||||
    "Active Mouse Button": "마우스 버튼 활성화",
 | 
			
		||||
    "No mousebutton": "마우스 버튼 없음",
 | 
			
		||||
    "Left mousebutton": "왼쪽 마우스 버튼",
 | 
			
		||||
    "Middle mousebutton": "중간 마우스 버튼",
 | 
			
		||||
    "Right mousebutton": "오른쪽 마우스 버튼",
 | 
			
		||||
    "Keyboard": "키보드",
 | 
			
		||||
    "Show Keyboard": "키보드 보이기",
 | 
			
		||||
    "Extra keys": "기타 키들",
 | 
			
		||||
    "Show Extra Keys": "기타 키들 보이기",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Ctrl 켜기/끄기",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Alt 켜기/끄기",
 | 
			
		||||
    "Send Tab": "Tab 보내기",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Esc 보내기",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Ctrl+Alt+Del 보내기",
 | 
			
		||||
    "Shutdown/Reboot": "셧다운/리붓",
 | 
			
		||||
    "Shutdown/Reboot...": "셧다운/리붓...",
 | 
			
		||||
    "Power": "전원",
 | 
			
		||||
    "Shutdown": "셧다운",
 | 
			
		||||
    "Reboot": "리붓",
 | 
			
		||||
    "Reset": "리셋",
 | 
			
		||||
    "Clipboard": "클립보드",
 | 
			
		||||
    "Clear": "지우기",
 | 
			
		||||
    "Fullscreen": "전체화면",
 | 
			
		||||
    "Settings": "설정",
 | 
			
		||||
    "Shared Mode": "공유 모드",
 | 
			
		||||
    "View Only": "보기 전용",
 | 
			
		||||
    "Clip to Window": "창에 클립",
 | 
			
		||||
    "Scaling Mode:": "스케일링 모드:",
 | 
			
		||||
    "None": "없음",
 | 
			
		||||
    "Local Scaling": "로컬 스케일링",
 | 
			
		||||
    "Remote Resizing": "원격 크기 조절",
 | 
			
		||||
    "Advanced": "고급",
 | 
			
		||||
    "Repeater ID:": "중계 ID",
 | 
			
		||||
    "WebSocket": "웹소켓",
 | 
			
		||||
    "Encrypt": "암호화",
 | 
			
		||||
    "Host:": "호스트:",
 | 
			
		||||
    "Port:": "포트:",
 | 
			
		||||
    "Path:": "위치:",
 | 
			
		||||
    "Automatic Reconnect": "자동 재연결",
 | 
			
		||||
    "Reconnect Delay (ms):": "재연결 지연 시간 (ms)",
 | 
			
		||||
    "Logging:": "로깅",
 | 
			
		||||
    "Disconnect": "연결 해제",
 | 
			
		||||
    "Connect": "연결",
 | 
			
		||||
    "Password:": "비밀번호:",
 | 
			
		||||
    "Send Password": "비밀번호 전송",
 | 
			
		||||
    "Cancel": "취소"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								VM/novnc/app/locale/nl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,73 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Verbinden...",
 | 
			
		||||
    "Disconnecting...": "Verbinding verbreken...",
 | 
			
		||||
    "Reconnecting...": "Opnieuw verbinding maken...",
 | 
			
		||||
    "Internal error": "Interne fout",
 | 
			
		||||
    "Must set host": "Host moeten worden ingesteld",
 | 
			
		||||
    "Connected (encrypted) to ": "Verbonden (versleuteld) met ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Verbonden (onversleuteld) met ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Er iets fout gelopen, verbinding werd verbroken",
 | 
			
		||||
    "Failed to connect to server": "Verbinding maken met server is mislukt",
 | 
			
		||||
    "Disconnected": "Verbinding verbroken",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Nieuwe verbinding is geweigerd omwille van de volgende reden: ",
 | 
			
		||||
    "New connection has been rejected": "Nieuwe verbinding is geweigerd",
 | 
			
		||||
    "Password is required": "Wachtwoord is vereist",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC heeft een fout bemerkt:",
 | 
			
		||||
    "Hide/Show the control bar": "Verberg/Toon de bedieningsbalk",
 | 
			
		||||
    "Move/Drag Viewport": "Verplaats/Versleep Kijkvenster",
 | 
			
		||||
    "viewport drag": "kijkvenster slepen",
 | 
			
		||||
    "Active Mouse Button": "Actieve Muisknop",
 | 
			
		||||
    "No mousebutton": "Geen muisknop",
 | 
			
		||||
    "Left mousebutton": "Linker muisknop",
 | 
			
		||||
    "Middle mousebutton": "Middelste muisknop",
 | 
			
		||||
    "Right mousebutton": "Rechter muisknop",
 | 
			
		||||
    "Keyboard": "Toetsenbord",
 | 
			
		||||
    "Show Keyboard": "Toon Toetsenbord",
 | 
			
		||||
    "Extra keys": "Extra toetsen",
 | 
			
		||||
    "Show Extra Keys": "Toon Extra Toetsen",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Ctrl omschakelen",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Alt omschakelen",
 | 
			
		||||
    "Toggle Windows": "Windows omschakelen",
 | 
			
		||||
    "Windows": "Windows",
 | 
			
		||||
    "Send Tab": "Tab Sturen",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Escape Sturen",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl-Alt-Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Ctrl-Alt-Del Sturen",
 | 
			
		||||
    "Shutdown/Reboot": "Uitschakelen/Herstarten",
 | 
			
		||||
    "Shutdown/Reboot...": "Uitschakelen/Herstarten...",
 | 
			
		||||
    "Power": "Systeem",
 | 
			
		||||
    "Shutdown": "Uitschakelen",
 | 
			
		||||
    "Reboot": "Herstarten",
 | 
			
		||||
    "Reset": "Resetten",
 | 
			
		||||
    "Clipboard": "Klembord",
 | 
			
		||||
    "Clear": "Wissen",
 | 
			
		||||
    "Fullscreen": "Volledig Scherm",
 | 
			
		||||
    "Settings": "Instellingen",
 | 
			
		||||
    "Shared Mode": "Gedeelde Modus",
 | 
			
		||||
    "View Only": "Alleen Kijken",
 | 
			
		||||
    "Clip to Window": "Randen buiten venster afsnijden",
 | 
			
		||||
    "Scaling Mode:": "Schaalmodus:",
 | 
			
		||||
    "None": "Geen",
 | 
			
		||||
    "Local Scaling": "Lokaal Schalen",
 | 
			
		||||
    "Remote Resizing": "Op Afstand Formaat Wijzigen",
 | 
			
		||||
    "Advanced": "Geavanceerd",
 | 
			
		||||
    "Repeater ID:": "Repeater ID:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Versleutelen",
 | 
			
		||||
    "Host:": "Host:",
 | 
			
		||||
    "Port:": "Poort:",
 | 
			
		||||
    "Path:": "Pad:",
 | 
			
		||||
    "Automatic Reconnect": "Automatisch Opnieuw Verbinden",
 | 
			
		||||
    "Reconnect Delay (ms):": "Vertraging voor Opnieuw Verbinden (ms):",
 | 
			
		||||
    "Show Dot when No Cursor": "Geef stip weer indien geen cursor",
 | 
			
		||||
    "Logging:": "Logmeldingen:",
 | 
			
		||||
    "Disconnect": "Verbinding verbreken",
 | 
			
		||||
    "Connect": "Verbinden",
 | 
			
		||||
    "Password:": "Wachtwoord:",
 | 
			
		||||
    "Send Password": "Verzend Wachtwoord:",
 | 
			
		||||
    "Cancel": "Annuleren"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								VM/novnc/app/locale/pl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,69 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Łączenie...",
 | 
			
		||||
    "Disconnecting...": "Rozłączanie...",
 | 
			
		||||
    "Reconnecting...": "Łączenie...",
 | 
			
		||||
    "Internal error": "Błąd wewnętrzny",
 | 
			
		||||
    "Must set host": "Host i port są wymagane",
 | 
			
		||||
    "Connected (encrypted) to ": "Połączenie (szyfrowane) z ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Połączenie (nieszyfrowane) z ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Coś poszło źle, połączenie zostało zamknięte",
 | 
			
		||||
    "Disconnected": "Rozłączony",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Nowe połączenie zostało odrzucone z powodu: ",
 | 
			
		||||
    "New connection has been rejected": "Nowe połączenie zostało odrzucone",
 | 
			
		||||
    "Password is required": "Hasło jest wymagane",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC napotkało błąd:",
 | 
			
		||||
    "Hide/Show the control bar": "Pokaż/Ukryj pasek ustawień",
 | 
			
		||||
    "Move/Drag Viewport": "Ruszaj/Przeciągaj Viewport",
 | 
			
		||||
    "viewport drag": "przeciągnij viewport",
 | 
			
		||||
    "Active Mouse Button": "Aktywny Przycisk Myszy",
 | 
			
		||||
    "No mousebutton": "Brak przycisku myszy",
 | 
			
		||||
    "Left mousebutton": "Lewy przycisk myszy",
 | 
			
		||||
    "Middle mousebutton": "Środkowy przycisk myszy",
 | 
			
		||||
    "Right mousebutton": "Prawy przycisk myszy",
 | 
			
		||||
    "Keyboard": "Klawiatura",
 | 
			
		||||
    "Show Keyboard": "Pokaż klawiaturę",
 | 
			
		||||
    "Extra keys": "Przyciski dodatkowe",
 | 
			
		||||
    "Show Extra Keys": "Pokaż przyciski dodatkowe",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Przełącz Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Przełącz Alt",
 | 
			
		||||
    "Send Tab": "Wyślij Tab",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Wyślij Escape",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Wyślij Ctrl-Alt-Del",
 | 
			
		||||
    "Shutdown/Reboot": "Wyłącz/Uruchom ponownie",
 | 
			
		||||
    "Shutdown/Reboot...": "Wyłącz/Uruchom ponownie...",
 | 
			
		||||
    "Power": "Włączony",
 | 
			
		||||
    "Shutdown": "Wyłącz",
 | 
			
		||||
    "Reboot": "Uruchom ponownie",
 | 
			
		||||
    "Reset": "Resetuj",
 | 
			
		||||
    "Clipboard": "Schowek",
 | 
			
		||||
    "Clear": "Wyczyść",
 | 
			
		||||
    "Fullscreen": "Pełny ekran",
 | 
			
		||||
    "Settings": "Ustawienia",
 | 
			
		||||
    "Shared Mode": "Tryb Współdzielenia",
 | 
			
		||||
    "View Only": "Tylko Podgląd",
 | 
			
		||||
    "Clip to Window": "Przytnij do Okna",
 | 
			
		||||
    "Scaling Mode:": "Tryb Skalowania:",
 | 
			
		||||
    "None": "Brak",
 | 
			
		||||
    "Local Scaling": "Skalowanie lokalne",
 | 
			
		||||
    "Remote Resizing": "Skalowanie zdalne",
 | 
			
		||||
    "Advanced": "Zaawansowane",
 | 
			
		||||
    "Repeater ID:": "ID Repeatera:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Szyfrowanie",
 | 
			
		||||
    "Host:": "Host:",
 | 
			
		||||
    "Port:": "Port:",
 | 
			
		||||
    "Path:": "Ścieżka:",
 | 
			
		||||
    "Automatic Reconnect": "Automatycznie wznawiaj połączenie",
 | 
			
		||||
    "Reconnect Delay (ms):": "Opóźnienie wznawiania (ms):",
 | 
			
		||||
    "Logging:": "Poziom logowania:",
 | 
			
		||||
    "Disconnect": "Rozłącz",
 | 
			
		||||
    "Connect": "Połącz",
 | 
			
		||||
    "Password:": "Hasło:",
 | 
			
		||||
    "Cancel": "Anuluj",
 | 
			
		||||
    "Canvas not supported.": "Element Canvas nie jest wspierany."
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								VM/novnc/app/locale/pt_BR.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,72 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Conectando...",
 | 
			
		||||
    "Disconnecting...": "Desconectando...",
 | 
			
		||||
    "Reconnecting...": "Reconectando...",
 | 
			
		||||
    "Internal error": "Erro interno",
 | 
			
		||||
    "Must set host": "É necessário definir o host",
 | 
			
		||||
    "Connected (encrypted) to ": "Conectado (com criptografia) a ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Conectado (sem criptografia) a ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Algo deu errado. A conexão foi encerrada.",
 | 
			
		||||
    "Failed to connect to server": "Falha ao conectar-se ao servidor",
 | 
			
		||||
    "Disconnected": "Desconectado",
 | 
			
		||||
    "New connection has been rejected with reason: ": "A nova conexão foi rejeitada pelo motivo: ",
 | 
			
		||||
    "New connection has been rejected": "A nova conexão foi rejeitada",
 | 
			
		||||
    "Credentials are required": "Credenciais são obrigatórias",
 | 
			
		||||
    "noVNC encountered an error:": "O noVNC encontrou um erro:",
 | 
			
		||||
    "Hide/Show the control bar": "Esconder/mostrar a barra de controles",
 | 
			
		||||
    "Drag": "Arrastar",
 | 
			
		||||
    "Move/Drag Viewport": "Mover/arrastar a janela",
 | 
			
		||||
    "Keyboard": "Teclado",
 | 
			
		||||
    "Show Keyboard": "Mostrar teclado",
 | 
			
		||||
    "Extra keys": "Teclas adicionais",
 | 
			
		||||
    "Show Extra Keys": "Mostar teclas adicionais",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Pressionar/soltar Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Pressionar/soltar Alt",
 | 
			
		||||
    "Toggle Windows": "Pressionar/soltar Windows",
 | 
			
		||||
    "Windows": "Windows",
 | 
			
		||||
    "Send Tab": "Enviar Tab",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Enviar Esc",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Enviar Ctrl-Alt-Del",
 | 
			
		||||
    "Shutdown/Reboot": "Desligar/reiniciar",
 | 
			
		||||
    "Shutdown/Reboot...": "Desligar/reiniciar...",
 | 
			
		||||
    "Power": "Ligar",
 | 
			
		||||
    "Shutdown": "Desligar",
 | 
			
		||||
    "Reboot": "Reiniciar",
 | 
			
		||||
    "Reset": "Reiniciar (forçado)",
 | 
			
		||||
    "Clipboard": "Área de transferência",
 | 
			
		||||
    "Clear": "Limpar",
 | 
			
		||||
    "Fullscreen": "Tela cheia",
 | 
			
		||||
    "Settings": "Configurações",
 | 
			
		||||
    "Shared Mode": "Modo compartilhado",
 | 
			
		||||
    "View Only": "Apenas visualizar",
 | 
			
		||||
    "Clip to Window": "Recortar à janela",
 | 
			
		||||
    "Scaling Mode:": "Modo de dimensionamento:",
 | 
			
		||||
    "None": "Nenhum",
 | 
			
		||||
    "Local Scaling": "Local",
 | 
			
		||||
    "Remote Resizing": "Remoto",
 | 
			
		||||
    "Advanced": "Avançado",
 | 
			
		||||
    "Quality:": "Qualidade:",
 | 
			
		||||
    "Compression level:": "Nível de compressão:",
 | 
			
		||||
    "Repeater ID:": "ID do repetidor:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Criptografar",
 | 
			
		||||
    "Host:": "Host:",
 | 
			
		||||
    "Port:": "Porta:",
 | 
			
		||||
    "Path:": "Caminho:",
 | 
			
		||||
    "Automatic Reconnect": "Reconexão automática",
 | 
			
		||||
    "Reconnect Delay (ms):": "Atraso da reconexão (ms)",
 | 
			
		||||
    "Show Dot when No Cursor": "Mostrar ponto quando não há cursor",
 | 
			
		||||
    "Logging:": "Registros:",
 | 
			
		||||
    "Version:": "Versão:",
 | 
			
		||||
    "Disconnect": "Desconectar",
 | 
			
		||||
    "Connect": "Conectar",
 | 
			
		||||
    "Username:": "Nome de usuário:",
 | 
			
		||||
    "Password:": "Senha:",
 | 
			
		||||
    "Send Credentials": "Enviar credenciais",
 | 
			
		||||
    "Cancel": "Cancelar"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								VM/novnc/app/locale/ru.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,72 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Подключение...",
 | 
			
		||||
    "Disconnecting...": "Отключение...",
 | 
			
		||||
    "Reconnecting...": "Переподключение...",
 | 
			
		||||
    "Internal error": "Внутренняя ошибка",
 | 
			
		||||
    "Must set host": "Задайте имя сервера или IP",
 | 
			
		||||
    "Connected (encrypted) to ": "Подключено (с шифрованием) к ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Подключено (без шифрования) к ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Что-то пошло не так, подключение разорвано",
 | 
			
		||||
    "Failed to connect to server": "Ошибка подключения к серверу",
 | 
			
		||||
    "Disconnected": "Отключено",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Новое соединение отклонено по причине: ",
 | 
			
		||||
    "New connection has been rejected": "Новое соединение отклонено",
 | 
			
		||||
    "Credentials are required": "Требуются учетные данные",
 | 
			
		||||
    "noVNC encountered an error:": "Ошибка noVNC: ",
 | 
			
		||||
    "Hide/Show the control bar": "Скрыть/Показать контрольную панель",
 | 
			
		||||
    "Drag": "Переместить",
 | 
			
		||||
    "Move/Drag Viewport": "Переместить окно",
 | 
			
		||||
    "Keyboard": "Клавиатура",
 | 
			
		||||
    "Show Keyboard": "Показать клавиатуру",
 | 
			
		||||
    "Extra keys": "Дополнительные Кнопки",
 | 
			
		||||
    "Show Extra Keys": "Показать Дополнительные Кнопки",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Переключение нажатия Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Переключение нажатия Alt",
 | 
			
		||||
    "Toggle Windows": "Переключение вкладок",
 | 
			
		||||
    "Windows": "Вкладка",
 | 
			
		||||
    "Send Tab": "Передать нажатие Tab",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Передать нажатие Escape",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Передать нажатие Ctrl-Alt-Del",
 | 
			
		||||
    "Shutdown/Reboot": "Выключить/Перезагрузить",
 | 
			
		||||
    "Shutdown/Reboot...": "Выключить/Перезагрузить...",
 | 
			
		||||
    "Power": "Питание",
 | 
			
		||||
    "Shutdown": "Выключить",
 | 
			
		||||
    "Reboot": "Перезагрузить",
 | 
			
		||||
    "Reset": "Сброс",
 | 
			
		||||
    "Clipboard": "Буфер обмена",
 | 
			
		||||
    "Clear": "Очистить",
 | 
			
		||||
    "Fullscreen": "Во весь экран",
 | 
			
		||||
    "Settings": "Настройки",
 | 
			
		||||
    "Shared Mode": "Общий режим",
 | 
			
		||||
    "View Only": "Только Просмотр",
 | 
			
		||||
    "Clip to Window": "В окно",
 | 
			
		||||
    "Scaling Mode:": "Масштаб:",
 | 
			
		||||
    "None": "Нет",
 | 
			
		||||
    "Local Scaling": "Локльный масштаб",
 | 
			
		||||
    "Remote Resizing": "Удаленная перенастройка размера",
 | 
			
		||||
    "Advanced": "Дополнительно",
 | 
			
		||||
    "Quality:": "Качество",
 | 
			
		||||
    "Compression level:": "Уровень Сжатия",
 | 
			
		||||
    "Repeater ID:": "Идентификатор ID:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Шифрование",
 | 
			
		||||
    "Host:": "Сервер:",
 | 
			
		||||
    "Port:": "Порт:",
 | 
			
		||||
    "Path:": "Путь:",
 | 
			
		||||
    "Automatic Reconnect": "Автоматическое переподключение",
 | 
			
		||||
    "Reconnect Delay (ms):": "Задержка переподключения (мс):",
 | 
			
		||||
    "Show Dot when No Cursor": "Показать точку вместо курсора",
 | 
			
		||||
    "Logging:": "Лог:",
 | 
			
		||||
    "Version:": "Версия",
 | 
			
		||||
    "Disconnect": "Отключение",
 | 
			
		||||
    "Connect": "Подключение",
 | 
			
		||||
    "Username:": "Имя Пользователя",
 | 
			
		||||
    "Password:": "Пароль:",
 | 
			
		||||
    "Send Credentials": "Передача Учетных Данных",
 | 
			
		||||
    "Cancel": "Выход"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								VM/novnc/app/locale/sv.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,81 @@
 | 
			
		||||
{
 | 
			
		||||
    "Running without HTTPS is not recommended, crashes or other issues are likely.": "Det är ej rekommenderat att köra utan HTTPS, krascher och andra problem är troliga.",
 | 
			
		||||
    "Connecting...": "Ansluter...",
 | 
			
		||||
    "Disconnecting...": "Kopplar ner...",
 | 
			
		||||
    "Reconnecting...": "Återansluter...",
 | 
			
		||||
    "Internal error": "Internt fel",
 | 
			
		||||
    "Must set host": "Du måste specifiera en värd",
 | 
			
		||||
    "Failed to connect to server: ": "Misslyckades att ansluta till servern: ",
 | 
			
		||||
    "Connected (encrypted) to ": "Ansluten (krypterat) till ",
 | 
			
		||||
    "Connected (unencrypted) to ": "Ansluten (okrypterat) till ",
 | 
			
		||||
    "Something went wrong, connection is closed": "Något gick fel, anslutningen avslutades",
 | 
			
		||||
    "Failed to connect to server": "Misslyckades att ansluta till servern",
 | 
			
		||||
    "Disconnected": "Frånkopplad",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Ny anslutning har blivit nekad med följande skäl: ",
 | 
			
		||||
    "New connection has been rejected": "Ny anslutning har blivit nekad",
 | 
			
		||||
    "Credentials are required": "Användaruppgifter krävs",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC stötte på ett problem:",
 | 
			
		||||
    "Hide/Show the control bar": "Göm/Visa kontrollbaren",
 | 
			
		||||
    "Drag": "Dra",
 | 
			
		||||
    "Move/Drag Viewport": "Flytta/Dra Vyn",
 | 
			
		||||
    "Keyboard": "Tangentbord",
 | 
			
		||||
    "Show Keyboard": "Visa Tangentbord",
 | 
			
		||||
    "Extra keys": "Extraknappar",
 | 
			
		||||
    "Show Extra Keys": "Visa Extraknappar",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Växla Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Växla Alt",
 | 
			
		||||
    "Toggle Windows": "Växla Windows",
 | 
			
		||||
    "Windows": "Windows",
 | 
			
		||||
    "Send Tab": "Skicka Tab",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Skicka Escape",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Skicka Ctrl-Alt-Del",
 | 
			
		||||
    "Shutdown/Reboot": "Stäng av/Boota om",
 | 
			
		||||
    "Shutdown/Reboot...": "Stäng av/Boota om...",
 | 
			
		||||
    "Power": "Ström",
 | 
			
		||||
    "Shutdown": "Stäng av",
 | 
			
		||||
    "Reboot": "Boota om",
 | 
			
		||||
    "Reset": "Återställ",
 | 
			
		||||
    "Clipboard": "Urklipp",
 | 
			
		||||
    "Edit clipboard content in the textarea below.": "Redigera urklippets innehåll i fältet nedan.",
 | 
			
		||||
    "Full Screen": "Fullskärm",
 | 
			
		||||
    "Settings": "Inställningar",
 | 
			
		||||
    "Shared Mode": "Delat Läge",
 | 
			
		||||
    "View Only": "Endast Visning",
 | 
			
		||||
    "Clip to Window": "Begränsa till Fönster",
 | 
			
		||||
    "Scaling Mode:": "Skalningsläge:",
 | 
			
		||||
    "None": "Ingen",
 | 
			
		||||
    "Local Scaling": "Lokal Skalning",
 | 
			
		||||
    "Remote Resizing": "Ändra Storlek",
 | 
			
		||||
    "Advanced": "Avancerat",
 | 
			
		||||
    "Quality:": "Kvalitet:",
 | 
			
		||||
    "Compression level:": "Kompressionsnivå:",
 | 
			
		||||
    "Repeater ID:": "Repeater-ID:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Kryptera",
 | 
			
		||||
    "Host:": "Värd:",
 | 
			
		||||
    "Port:": "Port:",
 | 
			
		||||
    "Path:": "Sökväg:",
 | 
			
		||||
    "Automatic Reconnect": "Automatisk Återanslutning",
 | 
			
		||||
    "Reconnect Delay (ms):": "Fördröjning (ms):",
 | 
			
		||||
    "Show Dot when No Cursor": "Visa prick när ingen muspekare finns",
 | 
			
		||||
    "Logging:": "Loggning:",
 | 
			
		||||
    "Version:": "Version:",
 | 
			
		||||
    "Disconnect": "Koppla från",
 | 
			
		||||
    "Connect": "Anslut",
 | 
			
		||||
    "Server identity": "Server-identitet",
 | 
			
		||||
    "The server has provided the following identifying information:": "Servern har gett följande identifierande information:",
 | 
			
		||||
    "Fingerprint:": "Fingeravtryck:",
 | 
			
		||||
    "Please verify that the information is correct and press \"Approve\". Otherwise press \"Reject\".": "Kontrollera att informationen är korrekt och tryck sedan \"Godkänn\". Tryck annars \"Neka\".",
 | 
			
		||||
    "Approve": "Godkänn",
 | 
			
		||||
    "Reject": "Neka",
 | 
			
		||||
    "Credentials": "Användaruppgifter",
 | 
			
		||||
    "Username:": "Användarnamn:",
 | 
			
		||||
    "Password:": "Lösenord:",
 | 
			
		||||
    "Send Credentials": "Skicka Användaruppgifter",
 | 
			
		||||
    "Cancel": "Avbryt"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								VM/novnc/app/locale/tr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,69 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "Bağlanıyor...",
 | 
			
		||||
    "Disconnecting...": "Bağlantı kesiliyor...",
 | 
			
		||||
    "Reconnecting...": "Yeniden bağlantı kuruluyor...",
 | 
			
		||||
    "Internal error": "İç hata",
 | 
			
		||||
    "Must set host": "Sunucuyu kur",
 | 
			
		||||
    "Connected (encrypted) to ": "Bağlı (şifrelenmiş)",
 | 
			
		||||
    "Connected (unencrypted) to ": "Bağlandı (şifrelenmemiş)",
 | 
			
		||||
    "Something went wrong, connection is closed": "Bir şeyler ters gitti, bağlantı kesildi",
 | 
			
		||||
    "Disconnected": "Bağlantı kesildi",
 | 
			
		||||
    "New connection has been rejected with reason: ": "Bağlantı aşağıdaki nedenlerden dolayı reddedildi: ",
 | 
			
		||||
    "New connection has been rejected": "Bağlantı reddedildi",
 | 
			
		||||
    "Password is required": "Şifre gerekli",
 | 
			
		||||
    "noVNC encountered an error:": "Bir hata oluştu:",
 | 
			
		||||
    "Hide/Show the control bar": "Denetim masasını Gizle/Göster",
 | 
			
		||||
    "Move/Drag Viewport": "Görünümü Taşı/Sürükle",
 | 
			
		||||
    "viewport drag": "Görüntü penceresini sürükle",
 | 
			
		||||
    "Active Mouse Button": "Aktif Fare Düğmesi",
 | 
			
		||||
    "No mousebutton": "Fare düğmesi yok",
 | 
			
		||||
    "Left mousebutton": "Farenin sol düğmesi",
 | 
			
		||||
    "Middle mousebutton": "Farenin orta düğmesi",
 | 
			
		||||
    "Right mousebutton": "Farenin sağ düğmesi",
 | 
			
		||||
    "Keyboard": "Klavye",
 | 
			
		||||
    "Show Keyboard": "Klavye Düzenini Göster",
 | 
			
		||||
    "Extra keys": "Ekstra tuşlar",
 | 
			
		||||
    "Show Extra Keys": "Ekstra tuşları göster",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "Ctrl Değiştir ",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "Alt Değiştir",
 | 
			
		||||
    "Send Tab": "Sekme Gönder",
 | 
			
		||||
    "Tab": "Sekme",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "Boşluk Gönder",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl + Alt + Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "Ctrl-Alt-Del Gönder",
 | 
			
		||||
    "Shutdown/Reboot": "Kapat/Yeniden Başlat",
 | 
			
		||||
    "Shutdown/Reboot...": "Kapat/Yeniden Başlat...",
 | 
			
		||||
    "Power": "Güç",
 | 
			
		||||
    "Shutdown": "Kapat",
 | 
			
		||||
    "Reboot": "Yeniden Başlat",
 | 
			
		||||
    "Reset": "Sıfırla",
 | 
			
		||||
    "Clipboard": "Pano",
 | 
			
		||||
    "Clear": "Temizle",
 | 
			
		||||
    "Fullscreen": "Tam Ekran",
 | 
			
		||||
    "Settings": "Ayarlar",
 | 
			
		||||
    "Shared Mode": "Paylaşım Modu",
 | 
			
		||||
    "View Only": "Sadece Görüntüle",
 | 
			
		||||
    "Clip to Window": "Pencereye Tıkla",
 | 
			
		||||
    "Scaling Mode:": "Ölçekleme Modu:",
 | 
			
		||||
    "None": "Bilinmeyen",
 | 
			
		||||
    "Local Scaling": "Yerel Ölçeklendirme",
 | 
			
		||||
    "Remote Resizing": "Uzaktan Yeniden Boyutlandırma",
 | 
			
		||||
    "Advanced": "Gelişmiş",
 | 
			
		||||
    "Repeater ID:": "Tekralayıcı ID:",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "Şifrele",
 | 
			
		||||
    "Host:": "Ana makine:",
 | 
			
		||||
    "Port:": "Port:",
 | 
			
		||||
    "Path:": "Yol:",
 | 
			
		||||
    "Automatic Reconnect": "Otomatik Yeniden Bağlan",
 | 
			
		||||
    "Reconnect Delay (ms):": "Yeniden Bağlanma Süreci (ms):",
 | 
			
		||||
    "Logging:": "Giriş yapılıyor:",
 | 
			
		||||
    "Disconnect": "Bağlantıyı Kes",
 | 
			
		||||
    "Connect": "Bağlan",
 | 
			
		||||
    "Password:": "Parola:",
 | 
			
		||||
    "Cancel": "Vazgeç",
 | 
			
		||||
    "Canvas not supported.": "Tuval desteklenmiyor."
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								VM/novnc/app/locale/zh_CN.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,69 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "连接中...",
 | 
			
		||||
    "Connected (encrypted) to ": "已连接(已加密)到",
 | 
			
		||||
    "Connected (unencrypted) to ": "已连接(未加密)到",
 | 
			
		||||
    "Disconnecting...": "正在断开连接...",
 | 
			
		||||
    "Disconnected": "已断开连接",
 | 
			
		||||
    "Must set host": "必须设置主机",
 | 
			
		||||
    "Reconnecting...": "重新连接中...",
 | 
			
		||||
    "Password is required": "请提供密码",
 | 
			
		||||
    "Disconnect timeout": "超时断开",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC 遇到一个错误:",
 | 
			
		||||
    "Hide/Show the control bar": "显示/隐藏控制栏",
 | 
			
		||||
    "Move/Drag Viewport": "移动/拖动窗口",
 | 
			
		||||
    "viewport drag": "窗口拖动",
 | 
			
		||||
    "Active Mouse Button": "启动鼠标按键",
 | 
			
		||||
    "No mousebutton": "禁用鼠标按键",
 | 
			
		||||
    "Left mousebutton": "鼠标左键",
 | 
			
		||||
    "Middle mousebutton": "鼠标中键",
 | 
			
		||||
    "Right mousebutton": "鼠标右键",
 | 
			
		||||
    "Keyboard": "键盘",
 | 
			
		||||
    "Show Keyboard": "显示键盘",
 | 
			
		||||
    "Extra keys": "额外按键",
 | 
			
		||||
    "Show Extra Keys": "显示额外按键",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "切换 Ctrl",
 | 
			
		||||
    "Edit clipboard content in the textarea below.": "在下面的文本区域中编辑剪贴板内容。",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "切换 Alt",
 | 
			
		||||
    "Send Tab": "发送 Tab 键",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "发送 Escape 键",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl+Alt+Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "发送 Ctrl+Alt+Del 键",
 | 
			
		||||
    "Shutdown/Reboot": "关机/重启",
 | 
			
		||||
    "Shutdown/Reboot...": "关机/重启...",
 | 
			
		||||
    "Power": "电源",
 | 
			
		||||
    "Shutdown": "关机",
 | 
			
		||||
    "Reboot": "重启",
 | 
			
		||||
    "Reset": "重置",
 | 
			
		||||
    "Clipboard": "剪贴板",
 | 
			
		||||
    "Clear": "清除",
 | 
			
		||||
    "Fullscreen": "全屏",
 | 
			
		||||
    "Settings": "设置",
 | 
			
		||||
    "Encrypt": "加密",
 | 
			
		||||
    "Shared Mode": "分享模式",
 | 
			
		||||
    "View Only": "仅查看",
 | 
			
		||||
    "Clip to Window": "限制/裁切窗口大小",
 | 
			
		||||
    "Scaling Mode:": "缩放模式:",
 | 
			
		||||
    "None": "无",
 | 
			
		||||
    "Local Scaling": "本地缩放",
 | 
			
		||||
    "Local Downscaling": "降低本地尺寸",
 | 
			
		||||
    "Remote Resizing": "远程调整大小",
 | 
			
		||||
    "Advanced": "高级",
 | 
			
		||||
    "Local Cursor": "本地光标",
 | 
			
		||||
    "Repeater ID:": "中继站 ID",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Host:": "主机:",
 | 
			
		||||
    "Port:": "端口:",
 | 
			
		||||
    "Path:": "路径:",
 | 
			
		||||
    "Automatic Reconnect": "自动重新连接",
 | 
			
		||||
    "Reconnect Delay (ms):": "重新连接间隔 (ms):",
 | 
			
		||||
    "Logging:": "日志级别:",
 | 
			
		||||
    "Disconnect": "断开连接",
 | 
			
		||||
    "Connect": "连接",
 | 
			
		||||
    "Password:": "密码:",
 | 
			
		||||
    "Cancel": "取消",
 | 
			
		||||
    "Canvas not supported.": "不支持 Canvas。"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								VM/novnc/app/locale/zh_TW.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,69 @@
 | 
			
		||||
{
 | 
			
		||||
    "Connecting...": "連線中...",
 | 
			
		||||
    "Disconnecting...": "正在中斷連線...",
 | 
			
		||||
    "Reconnecting...": "重新連線中...",
 | 
			
		||||
    "Internal error": "內部錯誤",
 | 
			
		||||
    "Must set host": "請提供主機資訊",
 | 
			
		||||
    "Connected (encrypted) to ": "已加密連線到",
 | 
			
		||||
    "Connected (unencrypted) to ": "未加密連線到",
 | 
			
		||||
    "Something went wrong, connection is closed": "發生錯誤,連線已關閉",
 | 
			
		||||
    "Failed to connect to server": "無法連線到伺服器",
 | 
			
		||||
    "Disconnected": "連線已中斷",
 | 
			
		||||
    "New connection has been rejected with reason: ": "連線被拒絕,原因:",
 | 
			
		||||
    "New connection has been rejected": "連線被拒絕",
 | 
			
		||||
    "Password is required": "請提供密碼",
 | 
			
		||||
    "noVNC encountered an error:": "noVNC 遇到一個錯誤:",
 | 
			
		||||
    "Hide/Show the control bar": "顯示/隱藏控制列",
 | 
			
		||||
    "Move/Drag Viewport": "拖放顯示範圍",
 | 
			
		||||
    "viewport drag": "顯示範圍拖放",
 | 
			
		||||
    "Active Mouse Button": "啟用滑鼠按鍵",
 | 
			
		||||
    "No mousebutton": "無滑鼠按鍵",
 | 
			
		||||
    "Left mousebutton": "滑鼠左鍵",
 | 
			
		||||
    "Middle mousebutton": "滑鼠中鍵",
 | 
			
		||||
    "Right mousebutton": "滑鼠右鍵",
 | 
			
		||||
    "Keyboard": "鍵盤",
 | 
			
		||||
    "Show Keyboard": "顯示鍵盤",
 | 
			
		||||
    "Extra keys": "額外按鍵",
 | 
			
		||||
    "Show Extra Keys": "顯示額外按鍵",
 | 
			
		||||
    "Ctrl": "Ctrl",
 | 
			
		||||
    "Toggle Ctrl": "切換 Ctrl",
 | 
			
		||||
    "Alt": "Alt",
 | 
			
		||||
    "Toggle Alt": "切換 Alt",
 | 
			
		||||
    "Send Tab": "送出 Tab 鍵",
 | 
			
		||||
    "Tab": "Tab",
 | 
			
		||||
    "Esc": "Esc",
 | 
			
		||||
    "Send Escape": "送出 Escape 鍵",
 | 
			
		||||
    "Ctrl+Alt+Del": "Ctrl-Alt-Del",
 | 
			
		||||
    "Send Ctrl-Alt-Del": "送出 Ctrl-Alt-Del 快捷鍵",
 | 
			
		||||
    "Shutdown/Reboot": "關機/重新啟動",
 | 
			
		||||
    "Shutdown/Reboot...": "關機/重新啟動...",
 | 
			
		||||
    "Power": "電源",
 | 
			
		||||
    "Shutdown": "關機",
 | 
			
		||||
    "Reboot": "重新啟動",
 | 
			
		||||
    "Reset": "重設",
 | 
			
		||||
    "Clipboard": "剪貼簿",
 | 
			
		||||
    "Clear": "清除",
 | 
			
		||||
    "Fullscreen": "全螢幕",
 | 
			
		||||
    "Settings": "設定",
 | 
			
		||||
    "Shared Mode": "分享模式",
 | 
			
		||||
    "View Only": "僅檢視",
 | 
			
		||||
    "Clip to Window": "限制/裁切視窗大小",
 | 
			
		||||
    "Scaling Mode:": "縮放模式:",
 | 
			
		||||
    "None": "無",
 | 
			
		||||
    "Local Scaling": "本機縮放",
 | 
			
		||||
    "Remote Resizing": "遠端調整大小",
 | 
			
		||||
    "Advanced": "進階",
 | 
			
		||||
    "Repeater ID:": "中繼站 ID",
 | 
			
		||||
    "WebSocket": "WebSocket",
 | 
			
		||||
    "Encrypt": "加密",
 | 
			
		||||
    "Host:": "主機:",
 | 
			
		||||
    "Port:": "連接埠:",
 | 
			
		||||
    "Path:": "路徑:",
 | 
			
		||||
    "Automatic Reconnect": "自動重新連線",
 | 
			
		||||
    "Reconnect Delay (ms):": "重新連線間隔 (ms):",
 | 
			
		||||
    "Logging:": "日誌級別:",
 | 
			
		||||
    "Disconnect": "中斷連線",
 | 
			
		||||
    "Connect": "連線",
 | 
			
		||||
    "Password:": "密碼:",
 | 
			
		||||
    "Cancel": "取消"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										206
									
								
								VM/novnc/app/localization.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,206 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2018 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Localization Utilities
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export class Localizer {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        // Currently configured language
 | 
			
		||||
        this.language = 'en';
 | 
			
		||||
 | 
			
		||||
        // Current dictionary of translations
 | 
			
		||||
        this._dictionary = undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Configure suitable language based on user preferences
 | 
			
		||||
    async setup(supportedLanguages, baseURL) {
 | 
			
		||||
        this.language = 'en'; // Default: US English
 | 
			
		||||
        this._dictionary = undefined;
 | 
			
		||||
 | 
			
		||||
        this._setupLanguage(supportedLanguages);
 | 
			
		||||
        await this._setupDictionary(baseURL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setupLanguage(supportedLanguages) {
 | 
			
		||||
        /*
 | 
			
		||||
         * Navigator.languages only available in Chrome (32+) and FireFox (32+)
 | 
			
		||||
         * Fall back to navigator.language for other browsers
 | 
			
		||||
         */
 | 
			
		||||
        let userLanguages;
 | 
			
		||||
        if (typeof window.navigator.languages == 'object') {
 | 
			
		||||
            userLanguages = window.navigator.languages;
 | 
			
		||||
        } else {
 | 
			
		||||
            userLanguages = [navigator.language || navigator.userLanguage];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (let i = 0;i < userLanguages.length;i++) {
 | 
			
		||||
            const userLang = userLanguages[i]
 | 
			
		||||
                .toLowerCase()
 | 
			
		||||
                .replace("_", "-")
 | 
			
		||||
                .split("-");
 | 
			
		||||
 | 
			
		||||
            // First pass: perfect match
 | 
			
		||||
            for (let j = 0; j < supportedLanguages.length; j++) {
 | 
			
		||||
                const supLang = supportedLanguages[j]
 | 
			
		||||
                    .toLowerCase()
 | 
			
		||||
                    .replace("_", "-")
 | 
			
		||||
                    .split("-");
 | 
			
		||||
 | 
			
		||||
                if (userLang[0] !== supLang[0]) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (userLang[1] !== supLang[1]) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                this.language = supportedLanguages[j];
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Second pass: English fallback
 | 
			
		||||
            if (userLang[0] === 'en') {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Third pass pass: other fallback
 | 
			
		||||
            for (let j = 0;j < supportedLanguages.length;j++) {
 | 
			
		||||
                const supLang = supportedLanguages[j]
 | 
			
		||||
                    .toLowerCase()
 | 
			
		||||
                    .replace("_", "-")
 | 
			
		||||
                    .split("-");
 | 
			
		||||
 | 
			
		||||
                if (userLang[0] !== supLang[0]) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (supLang[1] !== undefined) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                this.language = supportedLanguages[j];
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _setupDictionary(baseURL) {
 | 
			
		||||
        if (baseURL) {
 | 
			
		||||
            if (!baseURL.endsWith("/")) {
 | 
			
		||||
                baseURL = baseURL + "/";
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            baseURL = "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.language === "en") {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let response = await fetch(baseURL + this.language + ".json");
 | 
			
		||||
        if (!response.ok) {
 | 
			
		||||
            throw Error("" + response.status + " " + response.statusText);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._dictionary = await response.json();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Retrieve localised text
 | 
			
		||||
    get(id) {
 | 
			
		||||
        if (typeof this._dictionary !== 'undefined' &&
 | 
			
		||||
            this._dictionary[id]) {
 | 
			
		||||
            return this._dictionary[id];
 | 
			
		||||
        } else {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Traverses the DOM and translates relevant fields
 | 
			
		||||
    // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
 | 
			
		||||
    translateDOM() {
 | 
			
		||||
        const self = this;
 | 
			
		||||
 | 
			
		||||
        function process(elem, enabled) {
 | 
			
		||||
            function isAnyOf(searchElement, items) {
 | 
			
		||||
                return items.indexOf(searchElement) !== -1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function translateString(str) {
 | 
			
		||||
                // We assume surrounding whitespace, and whitespace around line
 | 
			
		||||
                // breaks is just for source formatting
 | 
			
		||||
                str = str.split("\n").map(s => s.trim()).join(" ").trim();
 | 
			
		||||
                return self.get(str);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function translateAttribute(elem, attr) {
 | 
			
		||||
                const str = translateString(elem.getAttribute(attr));
 | 
			
		||||
                elem.setAttribute(attr, str);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function translateTextNode(node) {
 | 
			
		||||
                const str = translateString(node.data);
 | 
			
		||||
                node.data = str;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (elem.hasAttribute("translate")) {
 | 
			
		||||
                if (isAnyOf(elem.getAttribute("translate"), ["", "yes"])) {
 | 
			
		||||
                    enabled = true;
 | 
			
		||||
                } else if (isAnyOf(elem.getAttribute("translate"), ["no"])) {
 | 
			
		||||
                    enabled = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (enabled) {
 | 
			
		||||
                if (elem.hasAttribute("abbr") &&
 | 
			
		||||
                    elem.tagName === "TH") {
 | 
			
		||||
                    translateAttribute(elem, "abbr");
 | 
			
		||||
                }
 | 
			
		||||
                if (elem.hasAttribute("alt") &&
 | 
			
		||||
                    isAnyOf(elem.tagName, ["AREA", "IMG", "INPUT"])) {
 | 
			
		||||
                    translateAttribute(elem, "alt");
 | 
			
		||||
                }
 | 
			
		||||
                if (elem.hasAttribute("download") &&
 | 
			
		||||
                    isAnyOf(elem.tagName, ["A", "AREA"])) {
 | 
			
		||||
                    translateAttribute(elem, "download");
 | 
			
		||||
                }
 | 
			
		||||
                if (elem.hasAttribute("label") &&
 | 
			
		||||
                    isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP",
 | 
			
		||||
                                           "OPTION", "TRACK"])) {
 | 
			
		||||
                    translateAttribute(elem, "label");
 | 
			
		||||
                }
 | 
			
		||||
                // FIXME: Should update "lang"
 | 
			
		||||
                if (elem.hasAttribute("placeholder") &&
 | 
			
		||||
                    isAnyOf(elem.tagName, ["INPUT", "TEXTAREA"])) {
 | 
			
		||||
                    translateAttribute(elem, "placeholder");
 | 
			
		||||
                }
 | 
			
		||||
                if (elem.hasAttribute("title")) {
 | 
			
		||||
                    translateAttribute(elem, "title");
 | 
			
		||||
                }
 | 
			
		||||
                if (elem.hasAttribute("value") &&
 | 
			
		||||
                    elem.tagName === "INPUT" &&
 | 
			
		||||
                    isAnyOf(elem.getAttribute("type"), ["reset", "button", "submit"])) {
 | 
			
		||||
                    translateAttribute(elem, "value");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < elem.childNodes.length; i++) {
 | 
			
		||||
                const node = elem.childNodes[i];
 | 
			
		||||
                if (node.nodeType === node.ELEMENT_NODE) {
 | 
			
		||||
                    process(node, enabled);
 | 
			
		||||
                } else if (node.nodeType === node.TEXT_NODE && enabled) {
 | 
			
		||||
                    translateTextNode(node);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        process(document.body, true);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const l10n = new Localizer();
 | 
			
		||||
export default l10n.get.bind(l10n);
 | 
			
		||||
							
								
								
									
										4
									
								
								VM/novnc/app/sounds/CREDITS
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,4 @@
 | 
			
		||||
bell
 | 
			
		||||
        Copyright: Dr. Richard Boulanger et al
 | 
			
		||||
        URL: http://www.archive.org/details/Berklee44v12
 | 
			
		||||
        License: CC-BY Attribution 3.0 Unported
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/sounds/bell.mp3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/sounds/bell.oga
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/styles/Orbitron700.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								VM/novnc/app/styles/Orbitron700.woff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										922
									
								
								VM/novnc/app/styles/base.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,922 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC base CSS
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 * This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Z index layers:
 | 
			
		||||
 *
 | 
			
		||||
 * 0: Main screen
 | 
			
		||||
 * 10: Control bar
 | 
			
		||||
 * 50: Transition blocker
 | 
			
		||||
 * 60: Connection popups
 | 
			
		||||
 * 100: Status bar
 | 
			
		||||
 * ...
 | 
			
		||||
 * 1000: Javascript crash
 | 
			
		||||
 * ...
 | 
			
		||||
 * 10000: Max (used for polyfills)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * State variables (set on :root):
 | 
			
		||||
 *
 | 
			
		||||
 * noVNC_loading: Page is still loading
 | 
			
		||||
 * noVNC_connecting: Connecting to server
 | 
			
		||||
 * noVNC_reconnecting: Re-establishing a connection
 | 
			
		||||
 * noVNC_connected: Connected to server (most common state)
 | 
			
		||||
 * noVNC_disconnecting: Disconnecting from server
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
  font-family: sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
  margin:0;
 | 
			
		||||
  padding:0;
 | 
			
		||||
  /*Background image with light grey curve.*/
 | 
			
		||||
  background-color:#494949;
 | 
			
		||||
  background-repeat:no-repeat;
 | 
			
		||||
  background-position:right bottom;
 | 
			
		||||
  height:100%;
 | 
			
		||||
  touch-action: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html {
 | 
			
		||||
  height:100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_only_touch.noVNC_hidden {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_disabled {
 | 
			
		||||
  color: rgb(128, 128, 128);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Spinner
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.noVNC_spinner {
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_spinner, .noVNC_spinner::before, .noVNC_spinner::after {
 | 
			
		||||
  width: 10px;
 | 
			
		||||
  height: 10px;
 | 
			
		||||
  border-radius: 2px;
 | 
			
		||||
  box-shadow: -60px 10px 0 rgba(255, 255, 255, 0);
 | 
			
		||||
  animation: noVNC_spinner 1.0s linear infinite;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_spinner::before {
 | 
			
		||||
  content: "";
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  left: 0px;
 | 
			
		||||
  top: 0px;
 | 
			
		||||
  animation-delay: -0.1s;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_spinner::after {
 | 
			
		||||
  content: "";
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 0px;
 | 
			
		||||
  left: 0px;
 | 
			
		||||
  animation-delay: 0.1s;
 | 
			
		||||
}
 | 
			
		||||
@keyframes noVNC_spinner {
 | 
			
		||||
  0% { box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); width: 20px; }
 | 
			
		||||
  25% { box-shadow: 20px 10px 0 rgba(255, 255, 255, 1); width: 10px; }
 | 
			
		||||
  50% { box-shadow: 60px 10px 0 rgba(255, 255, 255, 0); width: 10px; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * WebKit centering hacks
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.noVNC_center {
 | 
			
		||||
  /*
 | 
			
		||||
   * This is a workaround because webkit misrenders transforms and
 | 
			
		||||
   * uses non-integer coordinates, resulting in blurry content.
 | 
			
		||||
   * Ideally we'd use "top: 50%; transform: translateY(-50%);" on
 | 
			
		||||
   * the objects instead.
 | 
			
		||||
   */
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  pointer-events: none;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_center > * {
 | 
			
		||||
  pointer-events: auto;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_vcenter {
 | 
			
		||||
  display: flex !important;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  margin: 0 !important;
 | 
			
		||||
  padding: 0 !important;
 | 
			
		||||
  pointer-events: none;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_vcenter > * {
 | 
			
		||||
  pointer-events: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Layering
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.noVNC_connect_layer {
 | 
			
		||||
  z-index: 60;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Fallback error
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#noVNC_fallback_error {
 | 
			
		||||
  z-index: 1000;
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
  /* Put a dark background in front of everything but the error,
 | 
			
		||||
     and don't let mouse events pass through */
 | 
			
		||||
  background: rgba(0, 0, 0, 0.8);
 | 
			
		||||
  pointer-events: all;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_fallback_error.noVNC_open {
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_fallback_error > div {
 | 
			
		||||
  max-width: calc(100vw - 30px - 30px);
 | 
			
		||||
  max-height: calc(100vh - 30px - 30px);
 | 
			
		||||
  overflow: auto;
 | 
			
		||||
 | 
			
		||||
  padding: 15px;
 | 
			
		||||
 | 
			
		||||
  transition: 0.5s ease-in-out;
 | 
			
		||||
 | 
			
		||||
  transform: translateY(-50px);
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
 | 
			
		||||
  background: rgba(200,55,55,0.8);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_fallback_error.noVNC_open > div {
 | 
			
		||||
  transform: translateY(0);
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_fallback_errormsg {
 | 
			
		||||
  font-weight: normal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_fallback_errormsg .noVNC_message {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  text-align: left;
 | 
			
		||||
  font-family: monospace;
 | 
			
		||||
  white-space: pre-wrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_fallback_error .noVNC_location {
 | 
			
		||||
  font-style: italic;
 | 
			
		||||
  font-size: 0.8em;
 | 
			
		||||
  color: rgba(255, 255, 255, 0.8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_fallback_error .noVNC_stack {
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  margin: 10px;
 | 
			
		||||
  font-size: 0.8em;
 | 
			
		||||
  text-align: left;
 | 
			
		||||
  font-family: monospace;
 | 
			
		||||
  white-space: pre;
 | 
			
		||||
  border: 1px solid rgba(0, 0, 0, 0.5);
 | 
			
		||||
  background: rgba(0, 0, 0, 0.2);
 | 
			
		||||
  overflow: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Control Bar
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#noVNC_control_bar_anchor {
 | 
			
		||||
  /* The anchor is needed to get z-stacking to work */
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  z-index: 10;
 | 
			
		||||
 | 
			
		||||
  transition: 0.5s ease-in-out;
 | 
			
		||||
 | 
			
		||||
  /* Edge misrenders animations wihthout this */
 | 
			
		||||
  transform: translateX(0);
 | 
			
		||||
}
 | 
			
		||||
:root.noVNC_connected #noVNC_control_bar_anchor.noVNC_idle {
 | 
			
		||||
  opacity: 0.8;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar_anchor.noVNC_right {
 | 
			
		||||
  left: auto;
 | 
			
		||||
  right: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_control_bar {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  left: -100%;
 | 
			
		||||
 | 
			
		||||
  transition: 0.5s ease-in-out;
 | 
			
		||||
 | 
			
		||||
  background-color: rgb(110, 132, 163);
 | 
			
		||||
  border-radius: 0 10px 10px 0;
 | 
			
		||||
 | 
			
		||||
  user-select: none;
 | 
			
		||||
  -webkit-user-select: none;
 | 
			
		||||
  -webkit-touch-callout: none; /* Disable iOS image long-press popup */
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar.noVNC_open {
 | 
			
		||||
  box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
 | 
			
		||||
  left: 0;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar::before {
 | 
			
		||||
  /* This extra element is to get a proper shadow */
 | 
			
		||||
  content: "";
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  z-index: -1;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  width: 30px;
 | 
			
		||||
  left: -30px;
 | 
			
		||||
  transition: box-shadow 0.5s ease-in-out;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar.noVNC_open::before {
 | 
			
		||||
  box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right #noVNC_control_bar {
 | 
			
		||||
  left: 100%;
 | 
			
		||||
  border-radius: 10px 0 0 10px;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right #noVNC_control_bar.noVNC_open {
 | 
			
		||||
  left: 0;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right #noVNC_control_bar::before {
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_control_bar_handle {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  left: -15px;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  transform: translateY(35px);
 | 
			
		||||
  width: calc(100% + 30px);
 | 
			
		||||
  height: 50px;
 | 
			
		||||
  z-index: -1;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  background-color: rgb(83, 99, 122);
 | 
			
		||||
  background-image: url("../images/handle_bg.svg");
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  background-position: right;
 | 
			
		||||
  box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.5);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar_handle:after {
 | 
			
		||||
  content: "";
 | 
			
		||||
  transition: transform 0.5s ease-in-out;
 | 
			
		||||
  background: url("../images/handle.svg");
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 22px; /* (50px-6px)/2 */
 | 
			
		||||
  right: 5px;
 | 
			
		||||
  width: 5px;
 | 
			
		||||
  height: 6px;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
 | 
			
		||||
  transform: translateX(1px) rotate(180deg);
 | 
			
		||||
}
 | 
			
		||||
:root:not(.noVNC_connected) #noVNC_control_bar_handle {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right #noVNC_control_bar_handle {
 | 
			
		||||
  background-position: left;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right #noVNC_control_bar_handle:after {
 | 
			
		||||
  left: 5px;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  transform: translateX(1px) rotate(180deg);
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
 | 
			
		||||
  transform: none;
 | 
			
		||||
}
 | 
			
		||||
/* Larger touch area for the handle, used when a touch screen is available */
 | 
			
		||||
#noVNC_control_bar_handle div {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  right: -35px;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  width: 50px;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
@media (any-pointer: coarse) {
 | 
			
		||||
  #noVNC_control_bar_handle div {
 | 
			
		||||
    display: initial;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right #noVNC_control_bar_handle div {
 | 
			
		||||
  left: -35px;
 | 
			
		||||
  right: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_control_bar > .noVNC_scroll {
 | 
			
		||||
  max-height: 100vh; /* Chrome is buggy with 100% */
 | 
			
		||||
  overflow-x: hidden;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
  padding: 0 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_control_bar > .noVNC_scroll > * {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin: 10px auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Control bar hint */
 | 
			
		||||
#noVNC_hint_anchor {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  right: -50px;
 | 
			
		||||
  left: auto;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar_anchor.noVNC_right + #noVNC_hint_anchor {
 | 
			
		||||
  left: -50px;
 | 
			
		||||
  right: auto;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar_hint {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  transform: scale(0);
 | 
			
		||||
  width: 100px;
 | 
			
		||||
  height: 50%;
 | 
			
		||||
  max-height: 600px;
 | 
			
		||||
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
  transition: 0.2s ease-in-out;
 | 
			
		||||
  background: transparent;
 | 
			
		||||
  box-shadow: 0 0 10px black, inset 0 0 10px 10px rgba(110, 132, 163, 0.8);
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  transition-delay: 0s;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar_hint.noVNC_active {
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
  transition-delay: 0.2s;
 | 
			
		||||
  transform: scale(1);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar_hint.noVNC_notransition {
 | 
			
		||||
  transition: none !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Control bar buttons */
 | 
			
		||||
#noVNC_control_bar .noVNC_button {
 | 
			
		||||
  padding: 4px 4px;
 | 
			
		||||
  vertical-align: middle;
 | 
			
		||||
  border:1px solid rgba(255, 255, 255, 0.2);
 | 
			
		||||
  border-radius: 6px;
 | 
			
		||||
  background-color: transparent;
 | 
			
		||||
  background-image: unset; /* we don't want the gradiant from input.css */
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar .noVNC_button.noVNC_selected {
 | 
			
		||||
  border-color: rgba(0, 0, 0, 0.8);
 | 
			
		||||
  background-color: rgba(0, 0, 0, 0.5);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar .noVNC_button.noVNC_selected:not(:disabled):hover {
 | 
			
		||||
  border-color: rgba(0, 0, 0, 0.4);
 | 
			
		||||
  background-color: rgba(0, 0, 0, 0.2);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar .noVNC_button:not(:disabled):hover {
 | 
			
		||||
  background-color: rgba(255, 255, 255, 0.2);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar .noVNC_button:not(:disabled):active {
 | 
			
		||||
  padding-top: 5px;
 | 
			
		||||
  padding-bottom: 3px;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_control_bar .noVNC_button.noVNC_hidden {
 | 
			
		||||
  display: none !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Android browsers don't properly update hover state if touch events are
 | 
			
		||||
 * intercepted, like they are when clicking on the remote screen. */
 | 
			
		||||
@media (any-pointer: coarse) {
 | 
			
		||||
  #noVNC_control_bar .noVNC_button:not(:disabled):hover {
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
  }
 | 
			
		||||
  #noVNC_control_bar .noVNC_button.noVNC_selected:not(:disabled):hover {
 | 
			
		||||
    border-color: rgba(0, 0, 0, 0.8);
 | 
			
		||||
    background-color: rgba(0, 0, 0, 0.5);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Panels */
 | 
			
		||||
.noVNC_panel {
 | 
			
		||||
  transform: translateX(25px);
 | 
			
		||||
 | 
			
		||||
  transition: 0.5s ease-in-out;
 | 
			
		||||
 | 
			
		||||
  box-sizing: border-box; /* so max-width don't have to care about padding */
 | 
			
		||||
  max-width: calc(100vw - 75px - 25px); /* minus left and right margins */
 | 
			
		||||
  max-height: 100vh; /* Chrome is buggy with 100% */
 | 
			
		||||
  overflow-x: hidden;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
 | 
			
		||||
  padding: 15px;
 | 
			
		||||
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  color: #000;
 | 
			
		||||
  border: 2px solid #E0E0E0;
 | 
			
		||||
  box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
 | 
			
		||||
}
 | 
			
		||||
.noVNC_panel.noVNC_open {
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
  transform: translateX(75px);
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right .noVNC_vcenter {
 | 
			
		||||
  left: auto;
 | 
			
		||||
  right: 0;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right .noVNC_panel {
 | 
			
		||||
  transform: translateX(-25px);
 | 
			
		||||
}
 | 
			
		||||
.noVNC_right .noVNC_panel.noVNC_open {
 | 
			
		||||
  transform: translateX(-75px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_panel > * {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin: 10px auto;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_panel > *:first-child {
 | 
			
		||||
  margin-top: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_panel > *:last-child {
 | 
			
		||||
  margin-bottom: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_panel hr {
 | 
			
		||||
  border: none;
 | 
			
		||||
  border-top: 1px solid rgb(192, 192, 192);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_panel label {
 | 
			
		||||
  display: block;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
  margin: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_panel li {
 | 
			
		||||
  margin: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_panel .noVNC_heading {
 | 
			
		||||
  background-color: rgb(110, 132, 163);
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
  /* Compensate for padding in image */
 | 
			
		||||
  padding-right: 8px;
 | 
			
		||||
  color: white;
 | 
			
		||||
  font-size: 20px;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_panel .noVNC_heading img {
 | 
			
		||||
  vertical-align: bottom;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_submit {
 | 
			
		||||
  float: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Expanders */
 | 
			
		||||
.noVNC_expander {
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_expander::before {
 | 
			
		||||
  content: url("../images/expander.svg");
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  margin-right: 5px;
 | 
			
		||||
  transition: 0.2s ease-in-out;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_expander.noVNC_open::before {
 | 
			
		||||
  transform: rotateZ(90deg);
 | 
			
		||||
}
 | 
			
		||||
.noVNC_expander ~ * {
 | 
			
		||||
  margin: 5px;
 | 
			
		||||
  margin-left: 10px;
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
  background: rgba(0, 0, 0, 0.05);
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_expander:not(.noVNC_open) ~ * {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Control bar content */
 | 
			
		||||
 | 
			
		||||
#noVNC_control_bar .noVNC_logo {
 | 
			
		||||
  font-size: 13px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_logo + hr {
 | 
			
		||||
    /* Remove all but top border */
 | 
			
		||||
    border: none;
 | 
			
		||||
    border-top: 1px solid rgba(255, 255, 255, 0.2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
:root:not(.noVNC_connected) #noVNC_view_drag_button {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* noVNC Touch Device only buttons */
 | 
			
		||||
:root:not(.noVNC_connected) #noVNC_mobile_buttons {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
@media not all and (any-pointer: coarse) {
 | 
			
		||||
  /* FIXME: The button for the virtual keyboard is the only button in this
 | 
			
		||||
            group of "mobile buttons". It is bad to assume that no touch
 | 
			
		||||
            devices have physical keyboards available. Hopefully we can get
 | 
			
		||||
            a media query for this:
 | 
			
		||||
            https://github.com/w3c/csswg-drafts/issues/3871 */
 | 
			
		||||
  :root.noVNC_connected #noVNC_mobile_buttons {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Extra manual keys */
 | 
			
		||||
:root:not(.noVNC_connected) #noVNC_toggle_extra_keys_button {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_modifiers {
 | 
			
		||||
  background-color: rgb(92, 92, 92);
 | 
			
		||||
  border: none;
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Shutdown/Reboot */
 | 
			
		||||
:root:not(.noVNC_connected) #noVNC_power_button {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_power {
 | 
			
		||||
}
 | 
			
		||||
#noVNC_power_buttons {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_power input[type=button] {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Clipboard */
 | 
			
		||||
:root:not(.noVNC_connected) #noVNC_clipboard_button {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_clipboard_text {
 | 
			
		||||
  width: 360px;
 | 
			
		||||
  min-width: 150px;
 | 
			
		||||
  height: 160px;
 | 
			
		||||
  min-height: 70px;
 | 
			
		||||
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  max-width: 100%;
 | 
			
		||||
  /* minus approximate height of title, height of subtitle, and margin */
 | 
			
		||||
  max-height: calc(100vh - 10em - 25px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Settings */
 | 
			
		||||
#noVNC_settings {
 | 
			
		||||
}
 | 
			
		||||
#noVNC_settings ul {
 | 
			
		||||
  list-style: none;
 | 
			
		||||
  padding: 0px;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_setting_port {
 | 
			
		||||
  width: 80px;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_setting_path {
 | 
			
		||||
  width: 100px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Version */
 | 
			
		||||
 | 
			
		||||
.noVNC_version_wrapper {
 | 
			
		||||
  font-size: small;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_version {
 | 
			
		||||
  margin-left: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Connection Controls */
 | 
			
		||||
:root:not(.noVNC_connected) #noVNC_disconnect_button {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Status Dialog
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#noVNC_status {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  z-index: 100;
 | 
			
		||||
  transform: translateY(-100%);
 | 
			
		||||
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
 | 
			
		||||
  transition: 0.5s ease-in-out;
 | 
			
		||||
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  align-content: center;
 | 
			
		||||
 | 
			
		||||
  line-height: 1.6;
 | 
			
		||||
  word-wrap: break-word;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
 | 
			
		||||
  border-bottom: 1px solid rgba(0, 0, 0, 0.9);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_status.noVNC_open {
 | 
			
		||||
  transform: translateY(0);
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_status::before {
 | 
			
		||||
  content: "";
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  width: 25px;
 | 
			
		||||
  height: 25px;
 | 
			
		||||
  margin-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_status.noVNC_status_normal {
 | 
			
		||||
  background: rgba(128,128,128,0.9);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_status.noVNC_status_normal::before {
 | 
			
		||||
  content: url("../images/info.svg") " ";
 | 
			
		||||
}
 | 
			
		||||
#noVNC_status.noVNC_status_error {
 | 
			
		||||
  background: rgba(200,55,55,0.9);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_status.noVNC_status_error::before {
 | 
			
		||||
  content: url("../images/error.svg") " ";
 | 
			
		||||
}
 | 
			
		||||
#noVNC_status.noVNC_status_warn {
 | 
			
		||||
  background: rgba(180,180,30,0.9);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_status.noVNC_status_warn::before {
 | 
			
		||||
  content: url("../images/warning.svg") " ";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Connect Dialog
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#noVNC_connect_dlg {
 | 
			
		||||
  transition: 0.5s ease-in-out;
 | 
			
		||||
 | 
			
		||||
  transform: scale(0, 0);
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_connect_dlg.noVNC_open {
 | 
			
		||||
  transform: scale(1, 1);
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_connect_dlg .noVNC_logo {
 | 
			
		||||
  transition: 0.5s ease-in-out;
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  margin-bottom: 10px;
 | 
			
		||||
 | 
			
		||||
  font-size: 80px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
}
 | 
			
		||||
@media (max-width: 440px) {
 | 
			
		||||
  #noVNC_connect_dlg {
 | 
			
		||||
    max-width: calc(100vw - 100px);
 | 
			
		||||
  }
 | 
			
		||||
  #noVNC_connect_dlg .noVNC_logo {
 | 
			
		||||
    font-size: calc(25vw - 30px);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#noVNC_connect_dlg div {
 | 
			
		||||
  padding: 12px;
 | 
			
		||||
 | 
			
		||||
  background-color: rgb(110, 132, 163);
 | 
			
		||||
  border-radius: 12px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  font-size: 20px;
 | 
			
		||||
 | 
			
		||||
  box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_connect_button {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  padding: 5px 30px;
 | 
			
		||||
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
 | 
			
		||||
  border-color: rgb(83, 99, 122);
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
 | 
			
		||||
  background: linear-gradient(to top, rgb(110, 132, 163), rgb(99, 119, 147));
 | 
			
		||||
  color: white;
 | 
			
		||||
 | 
			
		||||
  /* This avoids it jumping around when :active */
 | 
			
		||||
  vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_connect_button:hover {
 | 
			
		||||
  background: linear-gradient(to top, rgb(110, 132, 163), rgb(105, 125, 155));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_connect_button img {
 | 
			
		||||
  vertical-align: bottom;
 | 
			
		||||
  height: 1.3em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Server verification Dialog
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#noVNC_verify_server_dlg {
 | 
			
		||||
  position: relative;
 | 
			
		||||
 | 
			
		||||
  transform: translateY(-50px);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_verify_server_dlg.noVNC_open {
 | 
			
		||||
  transform: translateY(0);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_fingerprint_block {
 | 
			
		||||
  margin: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Password Dialog
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#noVNC_credentials_dlg {
 | 
			
		||||
  position: relative;
 | 
			
		||||
 | 
			
		||||
  transform: translateY(-50px);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_credentials_dlg.noVNC_open {
 | 
			
		||||
  transform: translateY(0);
 | 
			
		||||
}
 | 
			
		||||
#noVNC_username_block.noVNC_hidden,
 | 
			
		||||
#noVNC_password_block.noVNC_hidden {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Main Area
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Transition screen */
 | 
			
		||||
#noVNC_transition {
 | 
			
		||||
  transition: 0.5s ease-in-out;
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  right: 0;
 | 
			
		||||
 | 
			
		||||
  color: white;
 | 
			
		||||
  background: rgba(0, 0, 0, 0.5);
 | 
			
		||||
  z-index: 50;
 | 
			
		||||
 | 
			
		||||
  /*display: flex;*/
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
}
 | 
			
		||||
:root.noVNC_loading #noVNC_transition,
 | 
			
		||||
:root.noVNC_connecting #noVNC_transition,
 | 
			
		||||
:root.noVNC_disconnecting #noVNC_transition,
 | 
			
		||||
:root.noVNC_reconnecting #noVNC_transition {
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
  visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
:root:not(.noVNC_reconnecting) #noVNC_cancel_reconnect_button {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
#noVNC_transition_text {
 | 
			
		||||
  font-size: 1.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Main container */
 | 
			
		||||
#noVNC_container {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  background-color: #313131;
 | 
			
		||||
  border-bottom-right-radius: 800px 600px;
 | 
			
		||||
  /*border-top-left-radius: 800px 600px;*/
 | 
			
		||||
 | 
			
		||||
  /* If selection isn't disabled, long-pressing stuff in the sidebar
 | 
			
		||||
     can accidentally select the container or the canvas. This can
 | 
			
		||||
     happen when attempting to move the handle. */
 | 
			
		||||
  user-select: none;
 | 
			
		||||
  -webkit-user-select: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_keyboardinput {
 | 
			
		||||
  width: 1px;
 | 
			
		||||
  height: 1px;
 | 
			
		||||
  background-color: #fff;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  border: 0;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  left: -40px;
 | 
			
		||||
  z-index: -1;
 | 
			
		||||
  ime-mode: disabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*Default noVNC logo.*/
 | 
			
		||||
/* From: http://fonts.googleapis.com/css?family=Orbitron:700 */
 | 
			
		||||
@font-face {
 | 
			
		||||
  font-family: 'Orbitron';
 | 
			
		||||
  font-style: normal;
 | 
			
		||||
  font-weight: 700;
 | 
			
		||||
  src: local('?'), url('Orbitron700.woff') format('woff'),
 | 
			
		||||
                   url('Orbitron700.ttf') format('truetype');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.noVNC_logo {
 | 
			
		||||
  color:yellow;
 | 
			
		||||
  font-family: 'Orbitron', 'OrbitronTTF', sans-serif;
 | 
			
		||||
  line-height: 0.9;
 | 
			
		||||
  text-shadow: 0.1em 0.1em 0 black;
 | 
			
		||||
}
 | 
			
		||||
.noVNC_logo span{
 | 
			
		||||
  color:green;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#noVNC_bell {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ----------------------------------------
 | 
			
		||||
 * Media sizing
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@media screen and (max-width: 640px){
 | 
			
		||||
  #noVNC_logo {
 | 
			
		||||
    font-size: 150px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media screen and (min-width: 321px) and (max-width: 480px) {
 | 
			
		||||
  #noVNC_logo {
 | 
			
		||||
    font-size: 110px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media screen and (max-width: 320px) {
 | 
			
		||||
  #noVNC_logo {
 | 
			
		||||
    font-size: 90px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										281
									
								
								VM/novnc/app/styles/input.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,281 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC general input element CSS
 | 
			
		||||
 * Copyright (C) 2022 The noVNC Authors
 | 
			
		||||
 * noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 * This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Common for all inputs
 | 
			
		||||
 */
 | 
			
		||||
input, input::file-selector-button, button, select, textarea {
 | 
			
		||||
  /* Respect standard font settings */
 | 
			
		||||
  font: inherit;
 | 
			
		||||
 | 
			
		||||
  /* Disable default rendering */
 | 
			
		||||
  appearance: none;
 | 
			
		||||
  background: none;
 | 
			
		||||
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
  border: 1px solid rgb(192, 192, 192);
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  color: black;
 | 
			
		||||
  --bg-gradient: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240));
 | 
			
		||||
  background-image: var(--bg-gradient);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Buttons
 | 
			
		||||
 */
 | 
			
		||||
input[type=button],
 | 
			
		||||
input[type=color],
 | 
			
		||||
input[type=image],
 | 
			
		||||
input[type=reset],
 | 
			
		||||
input[type=submit],
 | 
			
		||||
input::file-selector-button,
 | 
			
		||||
button,
 | 
			
		||||
select {
 | 
			
		||||
  border-bottom-width: 2px;
 | 
			
		||||
 | 
			
		||||
  /* This avoids it jumping around when :active */
 | 
			
		||||
  vertical-align: middle;
 | 
			
		||||
  margin-top: 0;
 | 
			
		||||
 | 
			
		||||
  padding-left: 20px;
 | 
			
		||||
  padding-right: 20px;
 | 
			
		||||
 | 
			
		||||
  /* Disable Chrome's touch tap highlight */
 | 
			
		||||
  -webkit-tap-highlight-color: transparent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Select dropdowns
 | 
			
		||||
 */
 | 
			
		||||
select {
 | 
			
		||||
  --select-arrow: url('data:image/svg+xml;utf8, \
 | 
			
		||||
      <svg width="8" height="6" version="1.1" viewBox="0 0 8 6" \
 | 
			
		||||
           xmlns="http://www.w3.org/2000/svg"> \
 | 
			
		||||
          <path d="m6.5 1.5 -2.5 3 -2.5 -3 5 0" stroke-width="3" \
 | 
			
		||||
                stroke="rgb(31,31,31)" fill="none" \
 | 
			
		||||
                stroke-linecap="round" stroke-linejoin="round" /> \
 | 
			
		||||
      </svg>');
 | 
			
		||||
  background-image: var(--select-arrow), var(--bg-gradient);
 | 
			
		||||
  background-position: calc(100% - 7px), left top;
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  padding-right: calc(2*7px + 8px);
 | 
			
		||||
  padding-left: 7px;
 | 
			
		||||
}
 | 
			
		||||
/* FIXME: :active isn't set when the <select> is opened in Firefox:
 | 
			
		||||
          https://bugzilla.mozilla.org/show_bug.cgi?id=1805406 */
 | 
			
		||||
select:active {
 | 
			
		||||
  /* Rotated arrow */
 | 
			
		||||
  background-image: url('data:image/svg+xml;utf8, \
 | 
			
		||||
      <svg width="8" height="6" version="1.1" viewBox="0 0 8 6" \
 | 
			
		||||
           xmlns="http://www.w3.org/2000/svg" transform="rotate(180)" > \
 | 
			
		||||
          <path d="m6.5 1.5 -2.5 3 -2.5 -3 5 0" stroke-width="3" \
 | 
			
		||||
                stroke="rgb(31,31,31)" fill="none" \
 | 
			
		||||
                stroke-linecap="round" stroke-linejoin="round" /> \
 | 
			
		||||
      </svg>'), var(--bg-gradient);
 | 
			
		||||
}
 | 
			
		||||
option {
 | 
			
		||||
  color: black;
 | 
			
		||||
  background: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checkboxes
 | 
			
		||||
 */
 | 
			
		||||
input[type=checkbox] {
 | 
			
		||||
  display: inline-flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  background-color: white;
 | 
			
		||||
  background-image: unset;
 | 
			
		||||
  border: 1px solid dimgrey;
 | 
			
		||||
  border-radius: 3px;
 | 
			
		||||
  width: 13px;
 | 
			
		||||
  height: 13px;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  margin-right: 6px;
 | 
			
		||||
  vertical-align: bottom;
 | 
			
		||||
  transition: 0.2s background-color linear;
 | 
			
		||||
}
 | 
			
		||||
input[type=checkbox]:checked {
 | 
			
		||||
  background-color: rgb(110, 132, 163);
 | 
			
		||||
  border-color: rgb(110, 132, 163);
 | 
			
		||||
}
 | 
			
		||||
input[type=checkbox]:checked::after {
 | 
			
		||||
  content: "";
 | 
			
		||||
  display: block; /* width & height doesn't work on inline elements */
 | 
			
		||||
  width: 3px;
 | 
			
		||||
  height: 7px;
 | 
			
		||||
  border: 1px solid white;
 | 
			
		||||
  border-width: 0 2px 2px 0;
 | 
			
		||||
  transform: rotate(40deg) translateY(-1px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Radiobuttons
 | 
			
		||||
 */
 | 
			
		||||
input[type=radio] {
 | 
			
		||||
  border-radius: 50%;
 | 
			
		||||
  border: 1px solid dimgrey;
 | 
			
		||||
  width: 12px;
 | 
			
		||||
  height: 12px;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  margin-right: 6px;
 | 
			
		||||
  transition: 0.2s border linear;
 | 
			
		||||
}
 | 
			
		||||
input[type=radio]:checked {
 | 
			
		||||
  border: 6px solid rgb(110, 132, 163);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Range sliders
 | 
			
		||||
 */
 | 
			
		||||
input[type=range] {
 | 
			
		||||
  border: unset;
 | 
			
		||||
  border-radius: 3px;
 | 
			
		||||
  height: 20px;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  background: transparent;
 | 
			
		||||
}
 | 
			
		||||
/* -webkit-slider.. & -moz-range.. cant be in selector lists:
 | 
			
		||||
   https://bugs.chromium.org/p/chromium/issues/detail?id=1154623 */
 | 
			
		||||
input[type=range]::-webkit-slider-runnable-track {
 | 
			
		||||
  background-color: rgb(110, 132, 163);
 | 
			
		||||
  height: 6px;
 | 
			
		||||
  border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
input[type=range]::-moz-range-track {
 | 
			
		||||
  background-color: rgb(110, 132, 163);
 | 
			
		||||
  height: 6px;
 | 
			
		||||
  border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
input[type=range]::-webkit-slider-thumb {
 | 
			
		||||
  appearance: none;
 | 
			
		||||
  width: 18px;
 | 
			
		||||
  height: 20px;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  background-color: white;
 | 
			
		||||
  border: 1px solid dimgray;
 | 
			
		||||
  margin-top: -7px;
 | 
			
		||||
}
 | 
			
		||||
input[type=range]::-moz-range-thumb {
 | 
			
		||||
  appearance: none;
 | 
			
		||||
  width: 18px;
 | 
			
		||||
  height: 20px;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
  background-color: white;
 | 
			
		||||
  border: 1px solid dimgray;
 | 
			
		||||
  margin-top: -7px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * File choosers
 | 
			
		||||
 */
 | 
			
		||||
input[type=file] {
 | 
			
		||||
  background-image: none;
 | 
			
		||||
  border: none;
 | 
			
		||||
}
 | 
			
		||||
input::file-selector-button {
 | 
			
		||||
  margin-right: 6px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Hover
 | 
			
		||||
 */
 | 
			
		||||
input[type=button]:hover,
 | 
			
		||||
input[type=color]:hover,
 | 
			
		||||
input[type=image]:hover,
 | 
			
		||||
input[type=reset]:hover,
 | 
			
		||||
input[type=submit]:hover,
 | 
			
		||||
input::file-selector-button:hover,
 | 
			
		||||
button:hover {
 | 
			
		||||
  background-image: linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250));
 | 
			
		||||
}
 | 
			
		||||
select:hover {
 | 
			
		||||
  background-image: var(--select-arrow),
 | 
			
		||||
    linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250));
 | 
			
		||||
  background-position: calc(100% - 7px), left top;
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
}
 | 
			
		||||
@media (any-pointer: coarse) {
 | 
			
		||||
  /* We don't want a hover style after touch input */
 | 
			
		||||
  input[type=button]:hover,
 | 
			
		||||
  input[type=color]:hover,
 | 
			
		||||
  input[type=image]:hover,
 | 
			
		||||
  input[type=reset]:hover,
 | 
			
		||||
  input[type=submit]:hover,
 | 
			
		||||
  input::file-selector-button:hover,
 | 
			
		||||
  button:hover {
 | 
			
		||||
    background-image: var(--bg-gradient);
 | 
			
		||||
  }
 | 
			
		||||
  select:hover {
 | 
			
		||||
    background-image: var(--select-arrow), var(--bg-gradient);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Active (clicked)
 | 
			
		||||
 */
 | 
			
		||||
input[type=button]:active,
 | 
			
		||||
input[type=color]:active,
 | 
			
		||||
input[type=image]:active,
 | 
			
		||||
input[type=reset]:active,
 | 
			
		||||
input[type=submit]:active,
 | 
			
		||||
input::file-selector-button:active,
 | 
			
		||||
button:active,
 | 
			
		||||
select:active {
 | 
			
		||||
  border-bottom-width: 1px;
 | 
			
		||||
  margin-top: 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Focus (tab)
 | 
			
		||||
 */
 | 
			
		||||
input:focus-visible,
 | 
			
		||||
input:focus-visible::file-selector-button,
 | 
			
		||||
button:focus-visible,
 | 
			
		||||
select:focus-visible,
 | 
			
		||||
textarea:focus-visible {
 | 
			
		||||
  outline: 2px solid rgb(74, 144, 217);
 | 
			
		||||
  outline-offset: 1px;
 | 
			
		||||
}
 | 
			
		||||
input[type=file]:focus-visible {
 | 
			
		||||
  outline: none; /* We outline the button instead of the entire element */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Disabled
 | 
			
		||||
 */
 | 
			
		||||
input:disabled,
 | 
			
		||||
input:disabled::file-selector-button,
 | 
			
		||||
button:disabled,
 | 
			
		||||
select:disabled,
 | 
			
		||||
textarea:disabled {
 | 
			
		||||
  opacity: 0.4;
 | 
			
		||||
}
 | 
			
		||||
input[type=button]:disabled,
 | 
			
		||||
input[type=color]:disabled,
 | 
			
		||||
input[type=image]:disabled,
 | 
			
		||||
input[type=reset]:disabled,
 | 
			
		||||
input[type=submit]:disabled,
 | 
			
		||||
input:disabled::file-selector-button,
 | 
			
		||||
button:disabled,
 | 
			
		||||
select:disabled {
 | 
			
		||||
  background-image: var(--bg-gradient);
 | 
			
		||||
  border-bottom-width: 2px;
 | 
			
		||||
  margin-top: 0;
 | 
			
		||||
}
 | 
			
		||||
input[type=file]:disabled {
 | 
			
		||||
  background-image: none;
 | 
			
		||||
}
 | 
			
		||||
select:disabled {
 | 
			
		||||
  background-image: var(--select-arrow), var(--bg-gradient);
 | 
			
		||||
}
 | 
			
		||||
input[type=image]:disabled {
 | 
			
		||||
  /* See Firefox bug:
 | 
			
		||||
     https://bugzilla.mozilla.org/show_bug.cgi?id=1798304 */
 | 
			
		||||
  cursor: default;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1778
									
								
								VM/novnc/app/ui.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										250
									
								
								VM/novnc/app/webutil.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,250 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import * as Log from '../core/util/logging.js';
 | 
			
		||||
 | 
			
		||||
// init log level reading the logging HTTP param
 | 
			
		||||
export function initLogging(level) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    if (typeof level !== "undefined") {
 | 
			
		||||
        Log.initLogging(level);
 | 
			
		||||
    } else {
 | 
			
		||||
        const param = document.location.href.match(/logging=([A-Za-z0-9._-]*)/);
 | 
			
		||||
        Log.initLogging(param || undefined);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read a query string variable
 | 
			
		||||
// A URL with a query parameter can look like this (But will most probably get logged on the http server):
 | 
			
		||||
// https://www.example.com?myqueryparam=myvalue
 | 
			
		||||
//
 | 
			
		||||
// For privacy (Using a hastag #, the parameters will not be sent to the server)
 | 
			
		||||
// the url can be requested in the following way:
 | 
			
		||||
// https://www.example.com#myqueryparam=myvalue&password=secretvalue
 | 
			
		||||
//
 | 
			
		||||
// Even Mixing public and non public parameters will work:
 | 
			
		||||
// https://www.example.com?nonsecretparam=example.com#password=secretvalue
 | 
			
		||||
export function getQueryVar(name, defVal) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
 | 
			
		||||
          match = document.location.href.match(re);
 | 
			
		||||
    if (typeof defVal === 'undefined') { defVal = null; }
 | 
			
		||||
 | 
			
		||||
    if (match) {
 | 
			
		||||
        return decodeURIComponent(match[1]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return defVal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read a hash fragment variable
 | 
			
		||||
export function getHashVar(name, defVal) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    const re = new RegExp('.*[&#]' + name + '=([^&]*)'),
 | 
			
		||||
          match = document.location.hash.match(re);
 | 
			
		||||
    if (typeof defVal === 'undefined') { defVal = null; }
 | 
			
		||||
 | 
			
		||||
    if (match) {
 | 
			
		||||
        return decodeURIComponent(match[1]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return defVal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read a variable from the fragment or the query string
 | 
			
		||||
// Fragment takes precedence
 | 
			
		||||
export function getConfigVar(name, defVal) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    const val = getHashVar(name);
 | 
			
		||||
 | 
			
		||||
    if (val === null) {
 | 
			
		||||
        return getQueryVar(name, defVal);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// No days means only for this browser session
 | 
			
		||||
export function createCookie(name, value, days) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    let date, expires;
 | 
			
		||||
    if (days) {
 | 
			
		||||
        date = new Date();
 | 
			
		||||
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
 | 
			
		||||
        expires = "; expires=" + date.toGMTString();
 | 
			
		||||
    } else {
 | 
			
		||||
        expires = "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let secure;
 | 
			
		||||
    if (document.location.protocol === "https:") {
 | 
			
		||||
        secure = "; secure";
 | 
			
		||||
    } else {
 | 
			
		||||
        secure = "";
 | 
			
		||||
    }
 | 
			
		||||
    document.cookie = name + "=" + value + expires + "; path=/" + secure;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function readCookie(name, defaultValue) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    const nameEQ = name + "=";
 | 
			
		||||
    const ca = document.cookie.split(';');
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < ca.length; i += 1) {
 | 
			
		||||
        let c = ca[i];
 | 
			
		||||
        while (c.charAt(0) === ' ') {
 | 
			
		||||
            c = c.substring(1, c.length);
 | 
			
		||||
        }
 | 
			
		||||
        if (c.indexOf(nameEQ) === 0) {
 | 
			
		||||
            return c.substring(nameEQ.length, c.length);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (typeof defaultValue !== 'undefined') ? defaultValue : null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function eraseCookie(name) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    createCookie(name, "", -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setting handling.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
let settings = {};
 | 
			
		||||
 | 
			
		||||
export function initSettings() {
 | 
			
		||||
    if (!window.chrome || !window.chrome.storage) {
 | 
			
		||||
        settings = {};
 | 
			
		||||
        return Promise.resolve();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return new Promise(resolve => window.chrome.storage.sync.get(resolve))
 | 
			
		||||
        .then((cfg) => { settings = cfg; });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update the settings cache, but do not write to permanent storage
 | 
			
		||||
export function setSetting(name, value) {
 | 
			
		||||
    settings[name] = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// No days means only for this browser session
 | 
			
		||||
export function writeSetting(name, value) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    if (settings[name] === value) return;
 | 
			
		||||
    settings[name] = value;
 | 
			
		||||
    if (window.chrome && window.chrome.storage) {
 | 
			
		||||
        window.chrome.storage.sync.set(settings);
 | 
			
		||||
    } else {
 | 
			
		||||
        localStorageSet(name, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function readSetting(name, defaultValue) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    let value;
 | 
			
		||||
    if ((name in settings) || (window.chrome && window.chrome.storage)) {
 | 
			
		||||
        value = settings[name];
 | 
			
		||||
    } else {
 | 
			
		||||
        value = localStorageGet(name);
 | 
			
		||||
        settings[name] = value;
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof value === "undefined") {
 | 
			
		||||
        value = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (value === null && typeof defaultValue !== "undefined") {
 | 
			
		||||
        return defaultValue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function eraseSetting(name) {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    // Deleting here means that next time the setting is read when using local
 | 
			
		||||
    // storage, it will be pulled from local storage again.
 | 
			
		||||
    // If the setting in local storage is changed (e.g. in another tab)
 | 
			
		||||
    // between this delete and the next read, it could lead to an unexpected
 | 
			
		||||
    // value change.
 | 
			
		||||
    delete settings[name];
 | 
			
		||||
    if (window.chrome && window.chrome.storage) {
 | 
			
		||||
        window.chrome.storage.sync.remove(name);
 | 
			
		||||
    } else {
 | 
			
		||||
        localStorageRemove(name);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let loggedMsgs = [];
 | 
			
		||||
function logOnce(msg, level = "warn") {
 | 
			
		||||
    if (!loggedMsgs.includes(msg)) {
 | 
			
		||||
        switch (level) {
 | 
			
		||||
            case "error":
 | 
			
		||||
                Log.Error(msg);
 | 
			
		||||
                break;
 | 
			
		||||
            case "warn":
 | 
			
		||||
                Log.Warn(msg);
 | 
			
		||||
                break;
 | 
			
		||||
            case "debug":
 | 
			
		||||
                Log.Debug(msg);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                Log.Info(msg);
 | 
			
		||||
        }
 | 
			
		||||
        loggedMsgs.push(msg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let cookiesMsg = "Couldn't access noVNC settings, are cookies disabled?";
 | 
			
		||||
 | 
			
		||||
function localStorageGet(name) {
 | 
			
		||||
    let r;
 | 
			
		||||
    try {
 | 
			
		||||
        r = localStorage.getItem(name);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        if (e instanceof DOMException) {
 | 
			
		||||
            logOnce(cookiesMsg);
 | 
			
		||||
            logOnce("'localStorage.getItem(" + name + ")' failed: " + e,
 | 
			
		||||
                    "debug");
 | 
			
		||||
        } else {
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
function localStorageSet(name, value) {
 | 
			
		||||
    try {
 | 
			
		||||
        localStorage.setItem(name, value);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        if (e instanceof DOMException) {
 | 
			
		||||
            logOnce(cookiesMsg);
 | 
			
		||||
            logOnce("'localStorage.setItem(" + name + "," + value +
 | 
			
		||||
                    ")' failed: " + e, "debug");
 | 
			
		||||
        } else {
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
function localStorageRemove(name) {
 | 
			
		||||
    try {
 | 
			
		||||
        localStorage.removeItem(name);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        if (e instanceof DOMException) {
 | 
			
		||||
            logOnce(cookiesMsg);
 | 
			
		||||
            logOnce("'localStorage.removeItem(" + name + ")' failed: " + e,
 | 
			
		||||
                    "debug");
 | 
			
		||||
        } else {
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								VM/novnc/core/base64.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,104 @@
 | 
			
		||||
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
			
		||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
			
		||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
			
		||||
 | 
			
		||||
// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
 | 
			
		||||
 | 
			
		||||
import * as Log from './util/logging.js';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    /* Convert data (an array of integers) to a Base64 string. */
 | 
			
		||||
    toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
 | 
			
		||||
    base64Pad: '=',
 | 
			
		||||
 | 
			
		||||
    encode(data) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
        let result = '';
 | 
			
		||||
        const length = data.length;
 | 
			
		||||
        const lengthpad = (length % 3);
 | 
			
		||||
        // Convert every three bytes to 4 ascii characters.
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < (length - 2); i += 3) {
 | 
			
		||||
            result += this.toBase64Table[data[i] >> 2];
 | 
			
		||||
            result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
 | 
			
		||||
            result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
 | 
			
		||||
            result += this.toBase64Table[data[i + 2] & 0x3f];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
 | 
			
		||||
        const j = length - lengthpad;
 | 
			
		||||
        if (lengthpad === 2) {
 | 
			
		||||
            result += this.toBase64Table[data[j] >> 2];
 | 
			
		||||
            result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
 | 
			
		||||
            result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
 | 
			
		||||
            result += this.toBase64Table[64];
 | 
			
		||||
        } else if (lengthpad === 1) {
 | 
			
		||||
            result += this.toBase64Table[data[j] >> 2];
 | 
			
		||||
            result += this.toBase64Table[(data[j] & 0x03) << 4];
 | 
			
		||||
            result += this.toBase64Table[64];
 | 
			
		||||
            result += this.toBase64Table[64];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /* Convert Base64 data to a string */
 | 
			
		||||
    /* eslint-disable comma-spacing */
 | 
			
		||||
    toBinaryTable: [
 | 
			
		||||
        -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 | 
			
		||||
        -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 | 
			
		||||
        -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
 | 
			
		||||
        52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
 | 
			
		||||
        -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
 | 
			
		||||
        15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
 | 
			
		||||
        -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
 | 
			
		||||
        41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
 | 
			
		||||
    ],
 | 
			
		||||
    /* eslint-enable comma-spacing */
 | 
			
		||||
 | 
			
		||||
    decode(data, offset = 0) {
 | 
			
		||||
        let dataLength = data.indexOf('=') - offset;
 | 
			
		||||
        if (dataLength < 0) { dataLength = data.length - offset; }
 | 
			
		||||
 | 
			
		||||
        /* Every four characters is 3 resulting numbers */
 | 
			
		||||
        const resultLength = (dataLength >> 2) * 3 + Math.floor((dataLength % 4) / 1.5);
 | 
			
		||||
        const result = new Array(resultLength);
 | 
			
		||||
 | 
			
		||||
        // Convert one by one.
 | 
			
		||||
 | 
			
		||||
        let leftbits = 0; // number of bits decoded, but yet to be appended
 | 
			
		||||
        let leftdata = 0; // bits decoded, but yet to be appended
 | 
			
		||||
        for (let idx = 0, i = offset; i < data.length; i++) {
 | 
			
		||||
            const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
 | 
			
		||||
            const padding = (data.charAt(i) === this.base64Pad);
 | 
			
		||||
            // Skip illegal characters and whitespace
 | 
			
		||||
            if (c === -1) {
 | 
			
		||||
                Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Collect data into leftdata, update bitcount
 | 
			
		||||
            leftdata = (leftdata << 6) | c;
 | 
			
		||||
            leftbits += 6;
 | 
			
		||||
 | 
			
		||||
            // If we have 8 or more bits, append 8 bits to the result
 | 
			
		||||
            if (leftbits >= 8) {
 | 
			
		||||
                leftbits -= 8;
 | 
			
		||||
                // Append if not padding.
 | 
			
		||||
                if (!padding) {
 | 
			
		||||
                    result[idx++] = (leftdata >> leftbits) & 0xff;
 | 
			
		||||
                }
 | 
			
		||||
                leftdata &= (1 << leftbits) - 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If there are any bits left, the base64 string was corrupted
 | 
			
		||||
        if (leftbits) {
 | 
			
		||||
            const err = new Error('Corrupted base64 string');
 | 
			
		||||
            err.name = 'Base64-Error';
 | 
			
		||||
            throw err;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
}; /* End of Base64 namespace */
 | 
			
		||||
							
								
								
									
										178
									
								
								VM/novnc/core/crypto/aes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,178 @@
 | 
			
		||||
export class AESECBCipher {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._key = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get algorithm() {
 | 
			
		||||
        return { name: "AES-ECB" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static async importKey(key, _algorithm, extractable, keyUsages) {
 | 
			
		||||
        const cipher = new AESECBCipher;
 | 
			
		||||
        await cipher._importKey(key, extractable, keyUsages);
 | 
			
		||||
        return cipher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _importKey(key, extractable, keyUsages) {
 | 
			
		||||
        this._key = await window.crypto.subtle.importKey(
 | 
			
		||||
            "raw", key, {name: "AES-CBC"}, extractable, keyUsages);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async encrypt(_algorithm, plaintext) {
 | 
			
		||||
        const x = new Uint8Array(plaintext);
 | 
			
		||||
        if (x.length % 16 !== 0 || this._key === null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        const n = x.length / 16;
 | 
			
		||||
        for (let i = 0; i < n; i++) {
 | 
			
		||||
            const y = new Uint8Array(await window.crypto.subtle.encrypt({
 | 
			
		||||
                name: "AES-CBC",
 | 
			
		||||
                iv: new Uint8Array(16),
 | 
			
		||||
            }, this._key, x.slice(i * 16, i * 16 + 16))).slice(0, 16);
 | 
			
		||||
            x.set(y, i * 16);
 | 
			
		||||
        }
 | 
			
		||||
        return x;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class AESEAXCipher {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._rawKey = null;
 | 
			
		||||
        this._ctrKey = null;
 | 
			
		||||
        this._cbcKey = null;
 | 
			
		||||
        this._zeroBlock = new Uint8Array(16);
 | 
			
		||||
        this._prefixBlock0 = this._zeroBlock;
 | 
			
		||||
        this._prefixBlock1 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
 | 
			
		||||
        this._prefixBlock2 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get algorithm() {
 | 
			
		||||
        return { name: "AES-EAX" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _encryptBlock(block) {
 | 
			
		||||
        const encrypted = await window.crypto.subtle.encrypt({
 | 
			
		||||
            name: "AES-CBC",
 | 
			
		||||
            iv: this._zeroBlock,
 | 
			
		||||
        }, this._cbcKey, block);
 | 
			
		||||
        return new Uint8Array(encrypted).slice(0, 16);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _initCMAC() {
 | 
			
		||||
        const k1 = await this._encryptBlock(this._zeroBlock);
 | 
			
		||||
        const k2 = new Uint8Array(16);
 | 
			
		||||
        const v = k1[0] >>> 6;
 | 
			
		||||
        for (let i = 0; i < 15; i++) {
 | 
			
		||||
            k2[i] = (k1[i + 1] >> 6) | (k1[i] << 2);
 | 
			
		||||
            k1[i] = (k1[i + 1] >> 7) | (k1[i] << 1);
 | 
			
		||||
        }
 | 
			
		||||
        const lut = [0x0, 0x87, 0x0e, 0x89];
 | 
			
		||||
        k2[14] ^= v >>> 1;
 | 
			
		||||
        k2[15] = (k1[15] << 2) ^ lut[v];
 | 
			
		||||
        k1[15] = (k1[15] << 1) ^ lut[v >> 1];
 | 
			
		||||
        this._k1 = k1;
 | 
			
		||||
        this._k2 = k2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _encryptCTR(data, counter) {
 | 
			
		||||
        const encrypted = await window.crypto.subtle.encrypt({
 | 
			
		||||
            name: "AES-CTR",
 | 
			
		||||
            counter: counter,
 | 
			
		||||
            length: 128
 | 
			
		||||
        }, this._ctrKey, data);
 | 
			
		||||
        return new Uint8Array(encrypted);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _decryptCTR(data, counter) {
 | 
			
		||||
        const decrypted = await window.crypto.subtle.decrypt({
 | 
			
		||||
            name: "AES-CTR",
 | 
			
		||||
            counter: counter,
 | 
			
		||||
            length: 128
 | 
			
		||||
        }, this._ctrKey, data);
 | 
			
		||||
        return new Uint8Array(decrypted);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _computeCMAC(data, prefixBlock) {
 | 
			
		||||
        if (prefixBlock.length !== 16) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        const n = Math.floor(data.length / 16);
 | 
			
		||||
        const m = Math.ceil(data.length / 16);
 | 
			
		||||
        const r = data.length - n * 16;
 | 
			
		||||
        const cbcData = new Uint8Array((m + 1) * 16);
 | 
			
		||||
        cbcData.set(prefixBlock);
 | 
			
		||||
        cbcData.set(data, 16);
 | 
			
		||||
        if (r === 0) {
 | 
			
		||||
            for (let i = 0; i < 16; i++) {
 | 
			
		||||
                cbcData[n * 16 + i] ^= this._k1[i];
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            cbcData[(n + 1) * 16 + r] = 0x80;
 | 
			
		||||
            for (let i = 0; i < 16; i++) {
 | 
			
		||||
                cbcData[(n + 1) * 16 + i] ^= this._k2[i];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        let cbcEncrypted = await window.crypto.subtle.encrypt({
 | 
			
		||||
            name: "AES-CBC",
 | 
			
		||||
            iv: this._zeroBlock,
 | 
			
		||||
        }, this._cbcKey, cbcData);
 | 
			
		||||
 | 
			
		||||
        cbcEncrypted = new Uint8Array(cbcEncrypted);
 | 
			
		||||
        const mac = cbcEncrypted.slice(cbcEncrypted.length - 32, cbcEncrypted.length - 16);
 | 
			
		||||
        return mac;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static async importKey(key, _algorithm, _extractable, _keyUsages) {
 | 
			
		||||
        const cipher = new AESEAXCipher;
 | 
			
		||||
        await cipher._importKey(key);
 | 
			
		||||
        return cipher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _importKey(key) {
 | 
			
		||||
        this._rawKey = key;
 | 
			
		||||
        this._ctrKey = await window.crypto.subtle.importKey(
 | 
			
		||||
            "raw", key, {name: "AES-CTR"}, false, ["encrypt", "decrypt"]);
 | 
			
		||||
        this._cbcKey = await window.crypto.subtle.importKey(
 | 
			
		||||
            "raw", key, {name: "AES-CBC"}, false, ["encrypt"]);
 | 
			
		||||
        await this._initCMAC();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async encrypt(algorithm, message) {
 | 
			
		||||
        const ad = algorithm.additionalData;
 | 
			
		||||
        const nonce = algorithm.iv;
 | 
			
		||||
        const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0);
 | 
			
		||||
        const encrypted = await this._encryptCTR(message, nCMAC);
 | 
			
		||||
        const adCMAC = await this._computeCMAC(ad, this._prefixBlock1);
 | 
			
		||||
        const mac = await this._computeCMAC(encrypted, this._prefixBlock2);
 | 
			
		||||
        for (let i = 0; i < 16; i++) {
 | 
			
		||||
            mac[i] ^= nCMAC[i] ^ adCMAC[i];
 | 
			
		||||
        }
 | 
			
		||||
        const res = new Uint8Array(16 + encrypted.length);
 | 
			
		||||
        res.set(encrypted);
 | 
			
		||||
        res.set(mac, encrypted.length);
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async decrypt(algorithm, data) {
 | 
			
		||||
        const encrypted = data.slice(0, data.length - 16);
 | 
			
		||||
        const ad = algorithm.additionalData;
 | 
			
		||||
        const nonce = algorithm.iv;
 | 
			
		||||
        const mac = data.slice(data.length - 16);
 | 
			
		||||
        const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0);
 | 
			
		||||
        const adCMAC = await this._computeCMAC(ad, this._prefixBlock1);
 | 
			
		||||
        const computedMac = await this._computeCMAC(encrypted, this._prefixBlock2);
 | 
			
		||||
        for (let i = 0; i < 16; i++) {
 | 
			
		||||
            computedMac[i] ^= nCMAC[i] ^ adCMAC[i];
 | 
			
		||||
        }
 | 
			
		||||
        if (computedMac.length !== mac.length) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        for (let i = 0; i < mac.length; i++) {
 | 
			
		||||
            if (computedMac[i] !== mac[i]) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        const res = await this._decryptCTR(encrypted, nCMAC);
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								VM/novnc/core/crypto/bigint.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,34 @@
 | 
			
		||||
export function modPow(b, e, m) {
 | 
			
		||||
    let r = 1n;
 | 
			
		||||
    b = b % m;
 | 
			
		||||
    while (e > 0n) {
 | 
			
		||||
        if ((e & 1n) === 1n) {
 | 
			
		||||
            r = (r * b) % m;
 | 
			
		||||
        }
 | 
			
		||||
        e = e >> 1n;
 | 
			
		||||
        b = (b * b) % m;
 | 
			
		||||
    }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function bigIntToU8Array(bigint, padLength=0) {
 | 
			
		||||
    let hex = bigint.toString(16);
 | 
			
		||||
    if (padLength === 0) {
 | 
			
		||||
        padLength = Math.ceil(hex.length / 2);
 | 
			
		||||
    }
 | 
			
		||||
    hex = hex.padStart(padLength * 2, '0');
 | 
			
		||||
    const length = hex.length / 2;
 | 
			
		||||
    const arr = new Uint8Array(length);
 | 
			
		||||
    for (let i = 0; i < length; i++) {
 | 
			
		||||
        arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
 | 
			
		||||
    }
 | 
			
		||||
    return arr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function u8ArrayToBigInt(arr) {
 | 
			
		||||
    let hex = '0x';
 | 
			
		||||
    for (let i = 0; i < arr.length; i++) {
 | 
			
		||||
        hex += arr[i].toString(16).padStart(2, '0');
 | 
			
		||||
    }
 | 
			
		||||
    return BigInt(hex);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								VM/novnc/core/crypto/crypto.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,90 @@
 | 
			
		||||
import { AESECBCipher, AESEAXCipher } from "./aes.js";
 | 
			
		||||
import { DESCBCCipher, DESECBCipher } from "./des.js";
 | 
			
		||||
import { RSACipher } from "./rsa.js";
 | 
			
		||||
import { DHCipher } from "./dh.js";
 | 
			
		||||
import { MD5 } from "./md5.js";
 | 
			
		||||
 | 
			
		||||
// A single interface for the cryptographic algorithms not supported by SubtleCrypto.
 | 
			
		||||
// Both synchronous and asynchronous implmentations are allowed.
 | 
			
		||||
class LegacyCrypto {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._algorithms = {
 | 
			
		||||
            "AES-ECB": AESECBCipher,
 | 
			
		||||
            "AES-EAX": AESEAXCipher,
 | 
			
		||||
            "DES-ECB": DESECBCipher,
 | 
			
		||||
            "DES-CBC": DESCBCCipher,
 | 
			
		||||
            "RSA-PKCS1-v1_5": RSACipher,
 | 
			
		||||
            "DH": DHCipher,
 | 
			
		||||
            "MD5": MD5,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    encrypt(algorithm, key, data) {
 | 
			
		||||
        if (key.algorithm.name !== algorithm.name) {
 | 
			
		||||
            throw new Error("algorithm does not match");
 | 
			
		||||
        }
 | 
			
		||||
        if (typeof key.encrypt !== "function") {
 | 
			
		||||
            throw new Error("key does not support encryption");
 | 
			
		||||
        }
 | 
			
		||||
        return key.encrypt(algorithm, data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    decrypt(algorithm, key, data) {
 | 
			
		||||
        if (key.algorithm.name !== algorithm.name) {
 | 
			
		||||
            throw new Error("algorithm does not match");
 | 
			
		||||
        }
 | 
			
		||||
        if (typeof key.decrypt !== "function") {
 | 
			
		||||
            throw new Error("key does not support encryption");
 | 
			
		||||
        }
 | 
			
		||||
        return key.decrypt(algorithm, data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    importKey(format, keyData, algorithm, extractable, keyUsages) {
 | 
			
		||||
        if (format !== "raw") {
 | 
			
		||||
            throw new Error("key format is not supported");
 | 
			
		||||
        }
 | 
			
		||||
        const alg = this._algorithms[algorithm.name];
 | 
			
		||||
        if (typeof alg === "undefined" || typeof alg.importKey !== "function") {
 | 
			
		||||
            throw new Error("algorithm is not supported");
 | 
			
		||||
        }
 | 
			
		||||
        return alg.importKey(keyData, algorithm, extractable, keyUsages);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    generateKey(algorithm, extractable, keyUsages) {
 | 
			
		||||
        const alg = this._algorithms[algorithm.name];
 | 
			
		||||
        if (typeof alg === "undefined" || typeof alg.generateKey !== "function") {
 | 
			
		||||
            throw new Error("algorithm is not supported");
 | 
			
		||||
        }
 | 
			
		||||
        return alg.generateKey(algorithm, extractable, keyUsages);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    exportKey(format, key) {
 | 
			
		||||
        if (format !== "raw") {
 | 
			
		||||
            throw new Error("key format is not supported");
 | 
			
		||||
        }
 | 
			
		||||
        if (typeof key.exportKey !== "function") {
 | 
			
		||||
            throw new Error("key does not support exportKey");
 | 
			
		||||
        }
 | 
			
		||||
        return key.exportKey();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    digest(algorithm, data) {
 | 
			
		||||
        const alg = this._algorithms[algorithm];
 | 
			
		||||
        if (typeof alg !== "function") {
 | 
			
		||||
            throw new Error("algorithm is not supported");
 | 
			
		||||
        }
 | 
			
		||||
        return alg(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    deriveBits(algorithm, key, length) {
 | 
			
		||||
        if (key.algorithm.name !== algorithm.name) {
 | 
			
		||||
            throw new Error("algorithm does not match");
 | 
			
		||||
        }
 | 
			
		||||
        if (typeof key.deriveBits !== "function") {
 | 
			
		||||
            throw new Error("key does not support deriveBits");
 | 
			
		||||
        }
 | 
			
		||||
        return key.deriveBits(algorithm, length);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new LegacyCrypto;
 | 
			
		||||
							
								
								
									
										330
									
								
								VM/novnc/core/crypto/des.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,330 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Ported from Flashlight VNC ActionScript implementation:
 | 
			
		||||
 *     http://www.wizhelp.com/flashlight-vnc/
 | 
			
		||||
 *
 | 
			
		||||
 * Full attribution follows:
 | 
			
		||||
 *
 | 
			
		||||
 * -------------------------------------------------------------------------
 | 
			
		||||
 *
 | 
			
		||||
 * This DES class has been extracted from package Acme.Crypto for use in VNC.
 | 
			
		||||
 * The unnecessary odd parity code has been removed.
 | 
			
		||||
 *
 | 
			
		||||
 * These changes are:
 | 
			
		||||
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * This software is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
 * DesCipher - the DES encryption method
 | 
			
		||||
 *
 | 
			
		||||
 * The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and distribute this software
 | 
			
		||||
 * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
 | 
			
		||||
 * without fee is hereby granted, provided that this copyright notice is kept
 | 
			
		||||
 * intact.
 | 
			
		||||
 *
 | 
			
		||||
 * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
 | 
			
		||||
 * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 | 
			
		||||
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 | 
			
		||||
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
 | 
			
		||||
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 | 
			
		||||
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
 | 
			
		||||
 * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
 | 
			
		||||
 * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
 | 
			
		||||
 * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
 | 
			
		||||
 * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
 | 
			
		||||
 * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
 | 
			
		||||
 * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  WIDGET WORKSHOP
 | 
			
		||||
 * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
 | 
			
		||||
 * HIGH RISK ACTIVITIES.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * The rest is:
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 | 
			
		||||
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
			
		||||
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * Visit the ACME Labs Java page for up-to-date versions of this and other
 | 
			
		||||
 * fine Java utilities: http://www.acme.com/java/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* eslint-disable comma-spacing */
 | 
			
		||||
 | 
			
		||||
// Tables, permutations, S-boxes, etc.
 | 
			
		||||
const PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3,
 | 
			
		||||
             25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39,
 | 
			
		||||
             50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31 ],
 | 
			
		||||
      totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28];
 | 
			
		||||
 | 
			
		||||
const z = 0x0;
 | 
			
		||||
let a,b,c,d,e,f;
 | 
			
		||||
a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e;
 | 
			
		||||
const SP1 = [c|e,z|z,a|z,c|f,c|d,a|f,z|d,a|z,z|e,c|e,c|f,z|e,b|f,c|d,b|z,z|d,
 | 
			
		||||
             z|f,b|e,b|e,a|e,a|e,c|z,c|z,b|f,a|d,b|d,b|d,a|d,z|z,z|f,a|f,b|z,
 | 
			
		||||
             a|z,c|f,z|d,c|z,c|e,b|z,b|z,z|e,c|d,a|z,a|e,b|d,z|e,z|d,b|f,a|f,
 | 
			
		||||
             c|f,a|d,c|z,b|f,b|d,z|f,a|f,c|e,z|f,b|e,b|e,z|z,a|d,a|e,z|z,c|d];
 | 
			
		||||
a=1<<20; b=1<<31; c=a|b; d=1<<5; e=1<<15; f=d|e;
 | 
			
		||||
const SP2 = [c|f,b|e,z|e,a|f,a|z,z|d,c|d,b|f,b|d,c|f,c|e,b|z,b|e,a|z,z|d,c|d,
 | 
			
		||||
             a|e,a|d,b|f,z|z,b|z,z|e,a|f,c|z,a|d,b|d,z|z,a|e,z|f,c|e,c|z,z|f,
 | 
			
		||||
             z|z,a|f,c|d,a|z,b|f,c|z,c|e,z|e,c|z,b|e,z|d,c|f,a|f,z|d,z|e,b|z,
 | 
			
		||||
             z|f,c|e,a|z,b|d,a|d,b|f,b|d,a|d,a|e,z|z,b|e,z|f,b|z,c|d,c|f,a|e];
 | 
			
		||||
a=1<<17; b=1<<27; c=a|b; d=1<<3; e=1<<9; f=d|e;
 | 
			
		||||
const SP3 = [z|f,c|e,z|z,c|d,b|e,z|z,a|f,b|e,a|d,b|d,b|d,a|z,c|f,a|d,c|z,z|f,
 | 
			
		||||
             b|z,z|d,c|e,z|e,a|e,c|z,c|d,a|f,b|f,a|e,a|z,b|f,z|d,c|f,z|e,b|z,
 | 
			
		||||
             c|e,b|z,a|d,z|f,a|z,c|e,b|e,z|z,z|e,a|d,c|f,b|e,b|d,z|e,z|z,c|d,
 | 
			
		||||
             b|f,a|z,b|z,c|f,z|d,a|f,a|e,b|d,c|z,b|f,z|f,c|z,a|f,z|d,c|d,a|e];
 | 
			
		||||
a=1<<13; b=1<<23; c=a|b; d=1<<0; e=1<<7; f=d|e;
 | 
			
		||||
const SP4 = [c|d,a|f,a|f,z|e,c|e,b|f,b|d,a|d,z|z,c|z,c|z,c|f,z|f,z|z,b|e,b|d,
 | 
			
		||||
             z|d,a|z,b|z,c|d,z|e,b|z,a|d,a|e,b|f,z|d,a|e,b|e,a|z,c|e,c|f,z|f,
 | 
			
		||||
             b|e,b|d,c|z,c|f,z|f,z|z,z|z,c|z,a|e,b|e,b|f,z|d,c|d,a|f,a|f,z|e,
 | 
			
		||||
             c|f,z|f,z|d,a|z,b|d,a|d,c|e,b|f,a|d,a|e,b|z,c|d,z|e,b|z,a|z,c|e];
 | 
			
		||||
a=1<<25; b=1<<30; c=a|b; d=1<<8; e=1<<19; f=d|e;
 | 
			
		||||
const SP5 = [z|d,a|f,a|e,c|d,z|e,z|d,b|z,a|e,b|f,z|e,a|d,b|f,c|d,c|e,z|f,b|z,
 | 
			
		||||
             a|z,b|e,b|e,z|z,b|d,c|f,c|f,a|d,c|e,b|d,z|z,c|z,a|f,a|z,c|z,z|f,
 | 
			
		||||
             z|e,c|d,z|d,a|z,b|z,a|e,c|d,b|f,a|d,b|z,c|e,a|f,b|f,z|d,a|z,c|e,
 | 
			
		||||
             c|f,z|f,c|z,c|f,a|e,z|z,b|e,c|z,z|f,a|d,b|d,z|e,z|z,b|e,a|f,b|d];
 | 
			
		||||
a=1<<22; b=1<<29; c=a|b; d=1<<4; e=1<<14; f=d|e;
 | 
			
		||||
const SP6 = [b|d,c|z,z|e,c|f,c|z,z|d,c|f,a|z,b|e,a|f,a|z,b|d,a|d,b|e,b|z,z|f,
 | 
			
		||||
             z|z,a|d,b|f,z|e,a|e,b|f,z|d,c|d,c|d,z|z,a|f,c|e,z|f,a|e,c|e,b|z,
 | 
			
		||||
             b|e,z|d,c|d,a|e,c|f,a|z,z|f,b|d,a|z,b|e,b|z,z|f,b|d,c|f,a|e,c|z,
 | 
			
		||||
             a|f,c|e,z|z,c|d,z|d,z|e,c|z,a|f,z|e,a|d,b|f,z|z,c|e,b|z,a|d,b|f];
 | 
			
		||||
a=1<<21; b=1<<26; c=a|b; d=1<<1; e=1<<11; f=d|e;
 | 
			
		||||
const SP7 = [a|z,c|d,b|f,z|z,z|e,b|f,a|f,c|e,c|f,a|z,z|z,b|d,z|d,b|z,c|d,z|f,
 | 
			
		||||
             b|e,a|f,a|d,b|e,b|d,c|z,c|e,a|d,c|z,z|e,z|f,c|f,a|e,z|d,b|z,a|e,
 | 
			
		||||
             b|z,a|e,a|z,b|f,b|f,c|d,c|d,z|d,a|d,b|z,b|e,a|z,c|e,z|f,a|f,c|e,
 | 
			
		||||
             z|f,b|d,c|f,c|z,a|e,z|z,z|d,c|f,z|z,a|f,c|z,z|e,b|d,b|e,z|e,a|d];
 | 
			
		||||
a=1<<18; b=1<<28; c=a|b; d=1<<6; e=1<<12; f=d|e;
 | 
			
		||||
const SP8 = [b|f,z|e,a|z,c|f,b|z,b|f,z|d,b|z,a|d,c|z,c|f,a|e,c|e,a|f,z|e,z|d,
 | 
			
		||||
             c|z,b|d,b|e,z|f,a|e,a|d,c|d,c|e,z|f,z|z,z|z,c|d,b|d,b|e,a|f,a|z,
 | 
			
		||||
             a|f,a|z,c|e,z|e,z|d,c|d,z|e,a|f,b|e,z|d,b|d,c|z,c|d,b|z,a|z,b|f,
 | 
			
		||||
             z|z,c|f,a|d,b|d,c|z,b|e,b|f,z|z,c|f,a|e,a|e,z|f,z|f,a|d,b|z,c|e];
 | 
			
		||||
 | 
			
		||||
/* eslint-enable comma-spacing */
 | 
			
		||||
 | 
			
		||||
class DES {
 | 
			
		||||
    constructor(password) {
 | 
			
		||||
        this.keys = [];
 | 
			
		||||
 | 
			
		||||
        // Set the key.
 | 
			
		||||
        const pc1m = [], pcr = [], kn = [];
 | 
			
		||||
 | 
			
		||||
        for (let j = 0, l = 56; j < 56; ++j, l -= 8) {
 | 
			
		||||
            l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1
 | 
			
		||||
            const m = l & 0x7;
 | 
			
		||||
            pc1m[j] = ((password[l >>> 3] & (1<<m)) !== 0) ? 1: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < 16; ++i) {
 | 
			
		||||
            const m = i << 1;
 | 
			
		||||
            const n = m + 1;
 | 
			
		||||
            kn[m] = kn[n] = 0;
 | 
			
		||||
            for (let o = 28; o < 59; o += 28) {
 | 
			
		||||
                for (let j = o - 28; j < o; ++j) {
 | 
			
		||||
                    const l = j + totrot[i];
 | 
			
		||||
                    pcr[j] = l < o ? pc1m[l] : pc1m[l - 28];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (let j = 0; j < 24; ++j) {
 | 
			
		||||
                if (pcr[PC2[j]] !== 0) {
 | 
			
		||||
                    kn[m] |= 1 << (23 - j);
 | 
			
		||||
                }
 | 
			
		||||
                if (pcr[PC2[j + 24]] !== 0) {
 | 
			
		||||
                    kn[n] |= 1 << (23 - j);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // cookey
 | 
			
		||||
        for (let i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
 | 
			
		||||
            const raw0 = kn[rawi++];
 | 
			
		||||
            const raw1 = kn[rawi++];
 | 
			
		||||
            this.keys[KnLi] = (raw0 & 0x00fc0000) << 6;
 | 
			
		||||
            this.keys[KnLi] |= (raw0 & 0x00000fc0) << 10;
 | 
			
		||||
            this.keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
 | 
			
		||||
            this.keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
 | 
			
		||||
            ++KnLi;
 | 
			
		||||
            this.keys[KnLi] = (raw0 & 0x0003f000) << 12;
 | 
			
		||||
            this.keys[KnLi] |= (raw0 & 0x0000003f) << 16;
 | 
			
		||||
            this.keys[KnLi] |= (raw1 & 0x0003f000) >>> 4;
 | 
			
		||||
            this.keys[KnLi] |= (raw1 & 0x0000003f);
 | 
			
		||||
            ++KnLi;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encrypt 8 bytes of text
 | 
			
		||||
    enc8(text) {
 | 
			
		||||
        const b = text.slice();
 | 
			
		||||
        let i = 0, l, r, x; // left, right, accumulator
 | 
			
		||||
 | 
			
		||||
        // Squash 8 bytes to 2 ints
 | 
			
		||||
        l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
 | 
			
		||||
        r = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
 | 
			
		||||
 | 
			
		||||
        x = ((l >>> 4) ^ r) & 0x0f0f0f0f;
 | 
			
		||||
        r ^= x;
 | 
			
		||||
        l ^= (x << 4);
 | 
			
		||||
        x = ((l >>> 16) ^ r) & 0x0000ffff;
 | 
			
		||||
        r ^= x;
 | 
			
		||||
        l ^= (x << 16);
 | 
			
		||||
        x = ((r >>> 2) ^ l) & 0x33333333;
 | 
			
		||||
        l ^= x;
 | 
			
		||||
        r ^= (x << 2);
 | 
			
		||||
        x = ((r >>> 8) ^ l) & 0x00ff00ff;
 | 
			
		||||
        l ^= x;
 | 
			
		||||
        r ^= (x << 8);
 | 
			
		||||
        r = (r << 1) | ((r >>> 31) & 1);
 | 
			
		||||
        x = (l ^ r) & 0xaaaaaaaa;
 | 
			
		||||
        l ^= x;
 | 
			
		||||
        r ^= x;
 | 
			
		||||
        l = (l << 1) | ((l >>> 31) & 1);
 | 
			
		||||
 | 
			
		||||
        for (let i = 0, keysi = 0; i < 8; ++i) {
 | 
			
		||||
            x = (r << 28) | (r >>> 4);
 | 
			
		||||
            x ^= this.keys[keysi++];
 | 
			
		||||
            let fval =  SP7[x & 0x3f];
 | 
			
		||||
            fval |= SP5[(x >>> 8) & 0x3f];
 | 
			
		||||
            fval |= SP3[(x >>> 16) & 0x3f];
 | 
			
		||||
            fval |= SP1[(x >>> 24) & 0x3f];
 | 
			
		||||
            x = r ^ this.keys[keysi++];
 | 
			
		||||
            fval |= SP8[x & 0x3f];
 | 
			
		||||
            fval |= SP6[(x >>> 8) & 0x3f];
 | 
			
		||||
            fval |= SP4[(x >>> 16) & 0x3f];
 | 
			
		||||
            fval |= SP2[(x >>> 24) & 0x3f];
 | 
			
		||||
            l ^= fval;
 | 
			
		||||
            x = (l << 28) | (l >>> 4);
 | 
			
		||||
            x ^= this.keys[keysi++];
 | 
			
		||||
            fval =  SP7[x & 0x3f];
 | 
			
		||||
            fval |= SP5[(x >>> 8) & 0x3f];
 | 
			
		||||
            fval |= SP3[(x >>> 16) & 0x3f];
 | 
			
		||||
            fval |= SP1[(x >>> 24) & 0x3f];
 | 
			
		||||
            x = l ^ this.keys[keysi++];
 | 
			
		||||
            fval |= SP8[x & 0x0000003f];
 | 
			
		||||
            fval |= SP6[(x >>> 8) & 0x3f];
 | 
			
		||||
            fval |= SP4[(x >>> 16) & 0x3f];
 | 
			
		||||
            fval |= SP2[(x >>> 24) & 0x3f];
 | 
			
		||||
            r ^= fval;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        r = (r << 31) | (r >>> 1);
 | 
			
		||||
        x = (l ^ r) & 0xaaaaaaaa;
 | 
			
		||||
        l ^= x;
 | 
			
		||||
        r ^= x;
 | 
			
		||||
        l = (l << 31) | (l >>> 1);
 | 
			
		||||
        x = ((l >>> 8) ^ r) & 0x00ff00ff;
 | 
			
		||||
        r ^= x;
 | 
			
		||||
        l ^= (x << 8);
 | 
			
		||||
        x = ((l >>> 2) ^ r) & 0x33333333;
 | 
			
		||||
        r ^= x;
 | 
			
		||||
        l ^= (x << 2);
 | 
			
		||||
        x = ((r >>> 16) ^ l) & 0x0000ffff;
 | 
			
		||||
        l ^= x;
 | 
			
		||||
        r ^= (x << 16);
 | 
			
		||||
        x = ((r >>> 4) ^ l) & 0x0f0f0f0f;
 | 
			
		||||
        l ^= x;
 | 
			
		||||
        r ^= (x << 4);
 | 
			
		||||
 | 
			
		||||
        // Spread ints to bytes
 | 
			
		||||
        x = [r, l];
 | 
			
		||||
        for (i = 0; i < 8; i++) {
 | 
			
		||||
            b[i] = (x[i>>>2] >>> (8 * (3 - (i % 4)))) % 256;
 | 
			
		||||
            if (b[i] < 0) { b[i] += 256; } // unsigned
 | 
			
		||||
        }
 | 
			
		||||
        return b;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class DESECBCipher {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._cipher = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get algorithm() {
 | 
			
		||||
        return { name: "DES-ECB" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static importKey(key, _algorithm, _extractable, _keyUsages) {
 | 
			
		||||
        const cipher = new DESECBCipher;
 | 
			
		||||
        cipher._importKey(key);
 | 
			
		||||
        return cipher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _importKey(key, _extractable, _keyUsages) {
 | 
			
		||||
        this._cipher = new DES(key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    encrypt(_algorithm, plaintext) {
 | 
			
		||||
        const x = new Uint8Array(plaintext);
 | 
			
		||||
        if (x.length % 8 !== 0 || this._cipher === null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        const n = x.length / 8;
 | 
			
		||||
        for (let i = 0; i < n; i++) {
 | 
			
		||||
            x.set(this._cipher.enc8(x.slice(i * 8, i * 8 + 8)), i * 8);
 | 
			
		||||
        }
 | 
			
		||||
        return x;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class DESCBCCipher {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._cipher = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get algorithm() {
 | 
			
		||||
        return { name: "DES-CBC" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static importKey(key, _algorithm, _extractable, _keyUsages) {
 | 
			
		||||
        const cipher = new DESCBCCipher;
 | 
			
		||||
        cipher._importKey(key);
 | 
			
		||||
        return cipher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _importKey(key) {
 | 
			
		||||
        this._cipher = new DES(key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    encrypt(algorithm, plaintext) {
 | 
			
		||||
        const x = new Uint8Array(plaintext);
 | 
			
		||||
        let y = new Uint8Array(algorithm.iv);
 | 
			
		||||
        if (x.length % 8 !== 0 || this._cipher === null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        const n = x.length / 8;
 | 
			
		||||
        for (let i = 0; i < n; i++) {
 | 
			
		||||
            for (let j = 0; j < 8; j++) {
 | 
			
		||||
                y[j] ^= plaintext[i * 8 + j];
 | 
			
		||||
            }
 | 
			
		||||
            y = this._cipher.enc8(y);
 | 
			
		||||
            x.set(y, i * 8);
 | 
			
		||||
        }
 | 
			
		||||
        return x;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								VM/novnc/core/crypto/dh.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,55 @@
 | 
			
		||||
import { modPow, bigIntToU8Array, u8ArrayToBigInt } from "./bigint.js";
 | 
			
		||||
 | 
			
		||||
class DHPublicKey {
 | 
			
		||||
    constructor(key) {
 | 
			
		||||
        this._key = key;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get algorithm() {
 | 
			
		||||
        return { name: "DH" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    exportKey() {
 | 
			
		||||
        return this._key;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class DHCipher {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._g = null;
 | 
			
		||||
        this._p = null;
 | 
			
		||||
        this._gBigInt = null;
 | 
			
		||||
        this._pBigInt = null;
 | 
			
		||||
        this._privateKey = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get algorithm() {
 | 
			
		||||
        return { name: "DH" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static generateKey(algorithm, _extractable) {
 | 
			
		||||
        const cipher = new DHCipher;
 | 
			
		||||
        cipher._generateKey(algorithm);
 | 
			
		||||
        return { privateKey: cipher, publicKey: new DHPublicKey(cipher._publicKey) };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _generateKey(algorithm) {
 | 
			
		||||
        const g = algorithm.g;
 | 
			
		||||
        const p = algorithm.p;
 | 
			
		||||
        this._keyBytes = p.length;
 | 
			
		||||
        this._gBigInt = u8ArrayToBigInt(g);
 | 
			
		||||
        this._pBigInt = u8ArrayToBigInt(p);
 | 
			
		||||
        this._privateKey = window.crypto.getRandomValues(new Uint8Array(this._keyBytes));
 | 
			
		||||
        this._privateKeyBigInt = u8ArrayToBigInt(this._privateKey);
 | 
			
		||||
        this._publicKey = bigIntToU8Array(modPow(
 | 
			
		||||
            this._gBigInt, this._privateKeyBigInt, this._pBigInt), this._keyBytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    deriveBits(algorithm, length) {
 | 
			
		||||
        const bytes = Math.ceil(length / 8);
 | 
			
		||||
        const pkey = new Uint8Array(algorithm.public);
 | 
			
		||||
        const len = bytes > this._keyBytes ? bytes : this._keyBytes;
 | 
			
		||||
        const secret = modPow(u8ArrayToBigInt(pkey), this._privateKeyBigInt, this._pBigInt);
 | 
			
		||||
        return bigIntToU8Array(secret, len).slice(0, len);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								VM/novnc/core/crypto/md5.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,82 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2021 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Performs MD5 hashing on an array of bytes, returns an array of bytes
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export async function MD5(d) {
 | 
			
		||||
    let s = "";
 | 
			
		||||
    for (let i = 0; i < d.length; i++) {
 | 
			
		||||
        s += String.fromCharCode(d[i]);
 | 
			
		||||
    }
 | 
			
		||||
    return M(V(Y(X(s), 8 * s.length)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function M(d) {
 | 
			
		||||
    let f = new Uint8Array(d.length);
 | 
			
		||||
    for (let i=0;i<d.length;i++) {
 | 
			
		||||
        f[i] = d.charCodeAt(i);
 | 
			
		||||
    }
 | 
			
		||||
    return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function X(d) {
 | 
			
		||||
    let r = Array(d.length >> 2);
 | 
			
		||||
    for (let m = 0; m < r.length; m++) r[m] = 0;
 | 
			
		||||
    for (let m = 0; m < 8 * d.length; m += 8) r[m >> 5] |= (255 & d.charCodeAt(m / 8)) << m % 32;
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function V(d) {
 | 
			
		||||
    let r = "";
 | 
			
		||||
    for (let m = 0; m < 32 * d.length; m += 8) r += String.fromCharCode(d[m >> 5] >>> m % 32 & 255);
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function Y(d, g) {
 | 
			
		||||
    d[g >> 5] |= 128 << g % 32, d[14 + (g + 64 >>> 9 << 4)] = g;
 | 
			
		||||
    let m = 1732584193, f = -271733879, r = -1732584194, i = 271733878;
 | 
			
		||||
    for (let n = 0; n < d.length; n += 16) {
 | 
			
		||||
        let h = m,
 | 
			
		||||
            t = f,
 | 
			
		||||
            g = r,
 | 
			
		||||
            e = i;
 | 
			
		||||
        f = ii(f = ii(f = ii(f = ii(f = hh(f = hh(f = hh(f = hh(f = gg(f = gg(f = gg(f = gg(f = ff(f = ff(f = ff(f = ff(f, r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 0], 7, -680876936), f, r, d[n + 1], 12, -389564586), m, f, d[n + 2], 17, 606105819), i, m, d[n + 3], 22, -1044525330), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 4], 7, -176418897), f, r, d[n + 5], 12, 1200080426), m, f, d[n + 6], 17, -1473231341), i, m, d[n + 7], 22, -45705983), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 8], 7, 1770035416), f, r, d[n + 9], 12, -1958414417), m, f, d[n + 10], 17, -42063), i, m, d[n + 11], 22, -1990404162), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 12], 7, 1804603682), f, r, d[n + 13], 12, -40341101), m, f, d[n + 14], 17, -1502002290), i, m, d[n + 15], 22, 1236535329), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 1], 5, -165796510), f, r, d[n + 6], 9, -1069501632), m, f, d[n + 11], 14, 643717713), i, m, d[n + 0], 20, -373897302), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 5], 5, -701558691), f, r, d[n + 10], 9, 38016083), m, f, d[n + 15], 14, -660478335), i, m, d[n + 4], 20, -405537848), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 9], 5, 568446438), f, r, d[n + 14], 9, -1019803690), m, f, d[n + 3], 14, -187363961), i, m, d[n + 8], 20, 1163531501), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 13], 5, -1444681467), f, r, d[n + 2], 9, -51403784), m, f, d[n + 7], 14, 1735328473), i, m, d[n + 12], 20, -1926607734), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 5], 4, -378558), f, r, d[n + 8], 11, -2022574463), m, f, d[n + 11], 16, 1839030562), i, m, d[n + 14], 23, -35309556), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 1], 4, -1530992060), f, r, d[n + 4], 11, 1272893353), m, f, d[n + 7], 16, -155497632), i, m, d[n + 10], 23, -1094730640), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 13], 4, 681279174), f, r, d[n + 0], 11, -358537222), m, f, d[n + 3], 16, -722521979), i, m, d[n + 6], 23, 76029189), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 9], 4, -640364487), f, r, d[n + 12], 11, -421815835), m, f, d[n + 15], 16, 530742520), i, m, d[n + 2], 23, -995338651), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 0], 6, -198630844), f, r, d[n + 7], 10, 1126891415), m, f, d[n + 14], 15, -1416354905), i, m, d[n + 5], 21, -57434055), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 12], 6, 1700485571), f, r, d[n + 3], 10, -1894986606), m, f, d[n + 10], 15, -1051523), i, m, d[n + 1], 21, -2054922799), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 8], 6, 1873313359), f, r, d[n + 15], 10, -30611744), m, f, d[n + 6], 15, -1560198380), i, m, d[n + 13], 21, 1309151649), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 4], 6, -145523070), f, r, d[n + 11], 10, -1120210379), m, f, d[n + 2], 15, 718787259), i, m, d[n + 9], 21, -343485551), m = add(m, h), f = add(f, t), r = add(r, g), i = add(i, e);
 | 
			
		||||
    }
 | 
			
		||||
    return Array(m, f, r, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function cmn(d, g, m, f, r, i) {
 | 
			
		||||
    return add(rol(add(add(g, d), add(f, i)), r), m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ff(d, g, m, f, r, i, n) {
 | 
			
		||||
    return cmn(g & m | ~g & f, d, g, r, i, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function gg(d, g, m, f, r, i, n) {
 | 
			
		||||
    return cmn(g & f | m & ~f, d, g, r, i, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function hh(d, g, m, f, r, i, n) {
 | 
			
		||||
    return cmn(g ^ m ^ f, d, g, r, i, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ii(d, g, m, f, r, i, n) {
 | 
			
		||||
    return cmn(m ^ (g | ~f), d, g, r, i, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function add(d, g) {
 | 
			
		||||
    let m = (65535 & d) + (65535 & g);
 | 
			
		||||
    return (d >> 16) + (g >> 16) + (m >> 16) << 16 | 65535 & m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function rol(d, g) {
 | 
			
		||||
    return d << g | d >>> 32 - g;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								VM/novnc/core/crypto/rsa.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,132 @@
 | 
			
		||||
import Base64 from "../base64.js";
 | 
			
		||||
import { modPow, bigIntToU8Array, u8ArrayToBigInt } from "./bigint.js";
 | 
			
		||||
 | 
			
		||||
export class RSACipher {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._keyLength = 0;
 | 
			
		||||
        this._keyBytes = 0;
 | 
			
		||||
        this._n = null;
 | 
			
		||||
        this._e = null;
 | 
			
		||||
        this._d = null;
 | 
			
		||||
        this._nBigInt = null;
 | 
			
		||||
        this._eBigInt = null;
 | 
			
		||||
        this._dBigInt = null;
 | 
			
		||||
        this._extractable = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get algorithm() {
 | 
			
		||||
        return { name: "RSA-PKCS1-v1_5" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _base64urlDecode(data) {
 | 
			
		||||
        data = data.replace(/-/g, "+").replace(/_/g, "/");
 | 
			
		||||
        data = data.padEnd(Math.ceil(data.length / 4) * 4, "=");
 | 
			
		||||
        return Base64.decode(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _padArray(arr, length) {
 | 
			
		||||
        const res = new Uint8Array(length);
 | 
			
		||||
        res.set(arr, length - arr.length);
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static async generateKey(algorithm, extractable, _keyUsages) {
 | 
			
		||||
        const cipher = new RSACipher;
 | 
			
		||||
        await cipher._generateKey(algorithm, extractable);
 | 
			
		||||
        return { privateKey: cipher };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _generateKey(algorithm, extractable) {
 | 
			
		||||
        this._keyLength = algorithm.modulusLength;
 | 
			
		||||
        this._keyBytes = Math.ceil(this._keyLength / 8);
 | 
			
		||||
        const key = await window.crypto.subtle.generateKey(
 | 
			
		||||
            {
 | 
			
		||||
                name: "RSA-OAEP",
 | 
			
		||||
                modulusLength: algorithm.modulusLength,
 | 
			
		||||
                publicExponent: algorithm.publicExponent,
 | 
			
		||||
                hash: {name: "SHA-256"},
 | 
			
		||||
            },
 | 
			
		||||
            true, ["encrypt", "decrypt"]);
 | 
			
		||||
        const privateKey = await window.crypto.subtle.exportKey("jwk", key.privateKey);
 | 
			
		||||
        this._n = this._padArray(this._base64urlDecode(privateKey.n), this._keyBytes);
 | 
			
		||||
        this._nBigInt = u8ArrayToBigInt(this._n);
 | 
			
		||||
        this._e = this._padArray(this._base64urlDecode(privateKey.e), this._keyBytes);
 | 
			
		||||
        this._eBigInt = u8ArrayToBigInt(this._e);
 | 
			
		||||
        this._d = this._padArray(this._base64urlDecode(privateKey.d), this._keyBytes);
 | 
			
		||||
        this._dBigInt = u8ArrayToBigInt(this._d);
 | 
			
		||||
        this._extractable = extractable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static async importKey(key, _algorithm, extractable, keyUsages) {
 | 
			
		||||
        if (keyUsages.length !== 1 || keyUsages[0] !== "encrypt") {
 | 
			
		||||
            throw new Error("only support importing RSA public key");
 | 
			
		||||
        }
 | 
			
		||||
        const cipher = new RSACipher;
 | 
			
		||||
        await cipher._importKey(key, extractable);
 | 
			
		||||
        return cipher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async _importKey(key, extractable) {
 | 
			
		||||
        const n = key.n;
 | 
			
		||||
        const e = key.e;
 | 
			
		||||
        if (n.length !== e.length) {
 | 
			
		||||
            throw new Error("the sizes of modulus and public exponent do not match");
 | 
			
		||||
        }
 | 
			
		||||
        this._keyBytes = n.length;
 | 
			
		||||
        this._keyLength = this._keyBytes * 8;
 | 
			
		||||
        this._n = new Uint8Array(this._keyBytes);
 | 
			
		||||
        this._e = new Uint8Array(this._keyBytes);
 | 
			
		||||
        this._n.set(n);
 | 
			
		||||
        this._e.set(e);
 | 
			
		||||
        this._nBigInt = u8ArrayToBigInt(this._n);
 | 
			
		||||
        this._eBigInt = u8ArrayToBigInt(this._e);
 | 
			
		||||
        this._extractable = extractable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async encrypt(_algorithm, message) {
 | 
			
		||||
        if (message.length > this._keyBytes - 11) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        const ps = new Uint8Array(this._keyBytes - message.length - 3);
 | 
			
		||||
        window.crypto.getRandomValues(ps);
 | 
			
		||||
        for (let i = 0; i < ps.length; i++) {
 | 
			
		||||
            ps[i] = Math.floor(ps[i] * 254 / 255 + 1);
 | 
			
		||||
        }
 | 
			
		||||
        const em = new Uint8Array(this._keyBytes);
 | 
			
		||||
        em[1] = 0x02;
 | 
			
		||||
        em.set(ps, 2);
 | 
			
		||||
        em.set(message, ps.length + 3);
 | 
			
		||||
        const emBigInt = u8ArrayToBigInt(em);
 | 
			
		||||
        const c = modPow(emBigInt, this._eBigInt, this._nBigInt);
 | 
			
		||||
        return bigIntToU8Array(c, this._keyBytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async decrypt(_algorithm, message) {
 | 
			
		||||
        if (message.length !== this._keyBytes) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        const msgBigInt = u8ArrayToBigInt(message);
 | 
			
		||||
        const emBigInt = modPow(msgBigInt, this._dBigInt, this._nBigInt);
 | 
			
		||||
        const em = bigIntToU8Array(emBigInt, this._keyBytes);
 | 
			
		||||
        if (em[0] !== 0x00 || em[1] !== 0x02) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        let i = 2;
 | 
			
		||||
        for (; i < em.length; i++) {
 | 
			
		||||
            if (em[i] === 0x00) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (i === em.length) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return em.slice(i + 1, em.length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async exportKey() {
 | 
			
		||||
        if (!this._extractable) {
 | 
			
		||||
            throw new Error("key is not extractable");
 | 
			
		||||
        }
 | 
			
		||||
        return { n: this._n, e: this._e, d: this._d };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								VM/novnc/core/decoders/copyrect.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,27 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export default class CopyRectDecoder {
 | 
			
		||||
    decodeRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if (sock.rQwait("COPYRECT", 4)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let deltaX = sock.rQshift16();
 | 
			
		||||
        let deltaY = sock.rQshift16();
 | 
			
		||||
 | 
			
		||||
        if ((width === 0) || (height === 0)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display.copyImage(deltaX, deltaY, x, y, width, height);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										181
									
								
								VM/novnc/core/decoders/hextile.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,181 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import * as Log from '../util/logging.js';
 | 
			
		||||
 | 
			
		||||
export default class HextileDecoder {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._tiles = 0;
 | 
			
		||||
        this._lastsubencoding = 0;
 | 
			
		||||
        this._tileBuffer = new Uint8Array(16 * 16 * 4);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    decodeRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if (this._tiles === 0) {
 | 
			
		||||
            this._tilesX = Math.ceil(width / 16);
 | 
			
		||||
            this._tilesY = Math.ceil(height / 16);
 | 
			
		||||
            this._totalTiles = this._tilesX * this._tilesY;
 | 
			
		||||
            this._tiles = this._totalTiles;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        while (this._tiles > 0) {
 | 
			
		||||
            let bytes = 1;
 | 
			
		||||
 | 
			
		||||
            if (sock.rQwait("HEXTILE", bytes)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let subencoding = sock.rQpeek8();
 | 
			
		||||
            if (subencoding > 30) {  // Raw
 | 
			
		||||
                throw new Error("Illegal hextile subencoding (subencoding: " +
 | 
			
		||||
                            subencoding + ")");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const currTile = this._totalTiles - this._tiles;
 | 
			
		||||
            const tileX = currTile % this._tilesX;
 | 
			
		||||
            const tileY = Math.floor(currTile / this._tilesX);
 | 
			
		||||
            const tx = x + tileX * 16;
 | 
			
		||||
            const ty = y + tileY * 16;
 | 
			
		||||
            const tw = Math.min(16, (x + width) - tx);
 | 
			
		||||
            const th = Math.min(16, (y + height) - ty);
 | 
			
		||||
 | 
			
		||||
            // Figure out how much we are expecting
 | 
			
		||||
            if (subencoding & 0x01) {  // Raw
 | 
			
		||||
                bytes += tw * th * 4;
 | 
			
		||||
            } else {
 | 
			
		||||
                if (subencoding & 0x02) {  // Background
 | 
			
		||||
                    bytes += 4;
 | 
			
		||||
                }
 | 
			
		||||
                if (subencoding & 0x04) {  // Foreground
 | 
			
		||||
                    bytes += 4;
 | 
			
		||||
                }
 | 
			
		||||
                if (subencoding & 0x08) {  // AnySubrects
 | 
			
		||||
                    bytes++;  // Since we aren't shifting it off
 | 
			
		||||
 | 
			
		||||
                    if (sock.rQwait("HEXTILE", bytes)) {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    let subrects = sock.rQpeekBytes(bytes).at(-1);
 | 
			
		||||
                    if (subencoding & 0x10) {  // SubrectsColoured
 | 
			
		||||
                        bytes += subrects * (4 + 2);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        bytes += subrects * 2;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (sock.rQwait("HEXTILE", bytes)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // We know the encoding and have a whole tile
 | 
			
		||||
            sock.rQshift8();
 | 
			
		||||
            if (subencoding === 0) {
 | 
			
		||||
                if (this._lastsubencoding & 0x01) {
 | 
			
		||||
                    // Weird: ignore blanks are RAW
 | 
			
		||||
                    Log.Debug("     Ignoring blank after RAW");
 | 
			
		||||
                } else {
 | 
			
		||||
                    display.fillRect(tx, ty, tw, th, this._background);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (subencoding & 0x01) {  // Raw
 | 
			
		||||
                let pixels = tw * th;
 | 
			
		||||
                let data = sock.rQshiftBytes(pixels * 4, false);
 | 
			
		||||
                // Max sure the image is fully opaque
 | 
			
		||||
                for (let i = 0;i <  pixels;i++) {
 | 
			
		||||
                    data[i * 4 + 3] = 255;
 | 
			
		||||
                }
 | 
			
		||||
                display.blitImage(tx, ty, tw, th, data, 0);
 | 
			
		||||
            } else {
 | 
			
		||||
                if (subencoding & 0x02) {  // Background
 | 
			
		||||
                    this._background = new Uint8Array(sock.rQshiftBytes(4));
 | 
			
		||||
                }
 | 
			
		||||
                if (subencoding & 0x04) {  // Foreground
 | 
			
		||||
                    this._foreground = new Uint8Array(sock.rQshiftBytes(4));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                this._startTile(tx, ty, tw, th, this._background);
 | 
			
		||||
                if (subencoding & 0x08) {  // AnySubrects
 | 
			
		||||
                    let subrects = sock.rQshift8();
 | 
			
		||||
 | 
			
		||||
                    for (let s = 0; s < subrects; s++) {
 | 
			
		||||
                        let color;
 | 
			
		||||
                        if (subencoding & 0x10) {  // SubrectsColoured
 | 
			
		||||
                            color = sock.rQshiftBytes(4);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            color = this._foreground;
 | 
			
		||||
                        }
 | 
			
		||||
                        const xy = sock.rQshift8();
 | 
			
		||||
                        const sx = (xy >> 4);
 | 
			
		||||
                        const sy = (xy & 0x0f);
 | 
			
		||||
 | 
			
		||||
                        const wh = sock.rQshift8();
 | 
			
		||||
                        const sw = (wh >> 4) + 1;
 | 
			
		||||
                        const sh = (wh & 0x0f) + 1;
 | 
			
		||||
 | 
			
		||||
                        this._subTile(sx, sy, sw, sh, color);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                this._finishTile(display);
 | 
			
		||||
            }
 | 
			
		||||
            this._lastsubencoding = subencoding;
 | 
			
		||||
            this._tiles--;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // start updating a tile
 | 
			
		||||
    _startTile(x, y, width, height, color) {
 | 
			
		||||
        this._tileX = x;
 | 
			
		||||
        this._tileY = y;
 | 
			
		||||
        this._tileW = width;
 | 
			
		||||
        this._tileH = height;
 | 
			
		||||
 | 
			
		||||
        const red = color[0];
 | 
			
		||||
        const green = color[1];
 | 
			
		||||
        const blue = color[2];
 | 
			
		||||
 | 
			
		||||
        const data = this._tileBuffer;
 | 
			
		||||
        for (let i = 0; i < width * height * 4; i += 4) {
 | 
			
		||||
            data[i]     = red;
 | 
			
		||||
            data[i + 1] = green;
 | 
			
		||||
            data[i + 2] = blue;
 | 
			
		||||
            data[i + 3] = 255;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // update sub-rectangle of the current tile
 | 
			
		||||
    _subTile(x, y, w, h, color) {
 | 
			
		||||
        const red = color[0];
 | 
			
		||||
        const green = color[1];
 | 
			
		||||
        const blue = color[2];
 | 
			
		||||
        const xend = x + w;
 | 
			
		||||
        const yend = y + h;
 | 
			
		||||
 | 
			
		||||
        const data = this._tileBuffer;
 | 
			
		||||
        const width = this._tileW;
 | 
			
		||||
        for (let j = y; j < yend; j++) {
 | 
			
		||||
            for (let i = x; i < xend; i++) {
 | 
			
		||||
                const p = (i + (j * width)) * 4;
 | 
			
		||||
                data[p]     = red;
 | 
			
		||||
                data[p + 1] = green;
 | 
			
		||||
                data[p + 2] = blue;
 | 
			
		||||
                data[p + 3] = 255;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // draw the current tile to the screen
 | 
			
		||||
    _finishTile(display) {
 | 
			
		||||
        display.blitImage(this._tileX, this._tileY,
 | 
			
		||||
                          this._tileW, this._tileH,
 | 
			
		||||
                          this._tileBuffer, 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										146
									
								
								VM/novnc/core/decoders/jpeg.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,146 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export default class JPEGDecoder {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        // RealVNC will reuse the quantization tables
 | 
			
		||||
        // and Huffman tables, so we need to cache them.
 | 
			
		||||
        this._cachedQuantTables = [];
 | 
			
		||||
        this._cachedHuffmanTables = [];
 | 
			
		||||
 | 
			
		||||
        this._segments = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    decodeRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        // A rect of JPEG encodings is simply a JPEG file
 | 
			
		||||
        while (true) {
 | 
			
		||||
            let segment = this._readSegment(sock);
 | 
			
		||||
            if (segment === null) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            this._segments.push(segment);
 | 
			
		||||
            // End of image?
 | 
			
		||||
            if (segment[1] === 0xD9) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let huffmanTables = [];
 | 
			
		||||
        let quantTables = [];
 | 
			
		||||
        for (let segment of this._segments) {
 | 
			
		||||
            let type = segment[1];
 | 
			
		||||
            if (type === 0xC4) {
 | 
			
		||||
                // Huffman tables
 | 
			
		||||
                huffmanTables.push(segment);
 | 
			
		||||
            } else if (type === 0xDB) {
 | 
			
		||||
                // Quantization tables
 | 
			
		||||
                quantTables.push(segment);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const sofIndex = this._segments.findIndex(
 | 
			
		||||
            x => x[1] == 0xC0 || x[1] == 0xC2
 | 
			
		||||
        );
 | 
			
		||||
        if (sofIndex == -1) {
 | 
			
		||||
            throw new Error("Illegal JPEG image without SOF");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (quantTables.length === 0) {
 | 
			
		||||
            this._segments.splice(sofIndex+1, 0,
 | 
			
		||||
                                  ...this._cachedQuantTables);
 | 
			
		||||
        }
 | 
			
		||||
        if (huffmanTables.length === 0) {
 | 
			
		||||
            this._segments.splice(sofIndex+1, 0,
 | 
			
		||||
                                  ...this._cachedHuffmanTables);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let length = 0;
 | 
			
		||||
        for (let segment of this._segments) {
 | 
			
		||||
            length += segment.length;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let data = new Uint8Array(length);
 | 
			
		||||
        length = 0;
 | 
			
		||||
        for (let segment of this._segments) {
 | 
			
		||||
            data.set(segment, length);
 | 
			
		||||
            length += segment.length;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display.imageRect(x, y, width, height, "image/jpeg", data);
 | 
			
		||||
 | 
			
		||||
        if (huffmanTables.length !== 0) {
 | 
			
		||||
            this._cachedHuffmanTables = huffmanTables;
 | 
			
		||||
        }
 | 
			
		||||
        if (quantTables.length !== 0) {
 | 
			
		||||
            this._cachedQuantTables = quantTables;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._segments = [];
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _readSegment(sock) {
 | 
			
		||||
        if (sock.rQwait("JPEG", 2)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let marker = sock.rQshift8();
 | 
			
		||||
        if (marker != 0xFF) {
 | 
			
		||||
            throw new Error("Illegal JPEG marker received (byte: " +
 | 
			
		||||
                               marker + ")");
 | 
			
		||||
        }
 | 
			
		||||
        let type = sock.rQshift8();
 | 
			
		||||
        if (type >= 0xD0 && type <= 0xD9 || type == 0x01) {
 | 
			
		||||
            // No length after marker
 | 
			
		||||
            return new Uint8Array([marker, type]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sock.rQwait("JPEG", 2, 2)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let length = sock.rQshift16();
 | 
			
		||||
        if (length < 2) {
 | 
			
		||||
            throw new Error("Illegal JPEG length received (length: " +
 | 
			
		||||
                               length + ")");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sock.rQwait("JPEG", length-2, 4)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let extra = 0;
 | 
			
		||||
        if (type === 0xDA) {
 | 
			
		||||
            // start of scan
 | 
			
		||||
            extra += 2;
 | 
			
		||||
            while (true) {
 | 
			
		||||
                if (sock.rQwait("JPEG", length-2+extra, 4)) {
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
                let data = sock.rQpeekBytes(length-2+extra, false);
 | 
			
		||||
                if (data.at(-2) === 0xFF && data.at(-1) !== 0x00 &&
 | 
			
		||||
                    !(data.at(-1) >= 0xD0 && data.at(-1) <= 0xD7)) {
 | 
			
		||||
                    extra -= 2;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                extra++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let segment = new Uint8Array(2 + length + extra);
 | 
			
		||||
        segment[0] = marker;
 | 
			
		||||
        segment[1] = type;
 | 
			
		||||
        segment[2] = length >> 8;
 | 
			
		||||
        segment[3] = length;
 | 
			
		||||
        segment.set(sock.rQshiftBytes(length-2+extra, false), 4);
 | 
			
		||||
 | 
			
		||||
        return segment;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								VM/novnc/core/decoders/raw.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,59 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export default class RawDecoder {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._lines = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    decodeRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if ((width === 0) || (height === 0)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._lines === 0) {
 | 
			
		||||
            this._lines = height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const pixelSize = depth == 8 ? 1 : 4;
 | 
			
		||||
        const bytesPerLine = width * pixelSize;
 | 
			
		||||
 | 
			
		||||
        while (this._lines > 0) {
 | 
			
		||||
            if (sock.rQwait("RAW", bytesPerLine)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const curY = y + (height - this._lines);
 | 
			
		||||
 | 
			
		||||
            let data = sock.rQshiftBytes(bytesPerLine, false);
 | 
			
		||||
 | 
			
		||||
            // Convert data if needed
 | 
			
		||||
            if (depth == 8) {
 | 
			
		||||
                const newdata = new Uint8Array(width * 4);
 | 
			
		||||
                for (let i = 0; i < width; i++) {
 | 
			
		||||
                    newdata[i * 4 + 0] = ((data[i] >> 0) & 0x3) * 255 / 3;
 | 
			
		||||
                    newdata[i * 4 + 1] = ((data[i] >> 2) & 0x3) * 255 / 3;
 | 
			
		||||
                    newdata[i * 4 + 2] = ((data[i] >> 4) & 0x3) * 255 / 3;
 | 
			
		||||
                    newdata[i * 4 + 3] = 255;
 | 
			
		||||
                }
 | 
			
		||||
                data = newdata;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Max sure the image is fully opaque
 | 
			
		||||
            for (let i = 0; i < width; i++) {
 | 
			
		||||
                data[i * 4 + 3] = 255;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            display.blitImage(x, curY, width, 1, data, 0);
 | 
			
		||||
            this._lines--;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								VM/novnc/core/decoders/rre.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,44 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export default class RREDecoder {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._subrects = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    decodeRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if (this._subrects === 0) {
 | 
			
		||||
            if (sock.rQwait("RRE", 4 + 4)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._subrects = sock.rQshift32();
 | 
			
		||||
 | 
			
		||||
            let color = sock.rQshiftBytes(4);  // Background
 | 
			
		||||
            display.fillRect(x, y, width, height, color);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        while (this._subrects > 0) {
 | 
			
		||||
            if (sock.rQwait("RRE", 4 + 8)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let color = sock.rQshiftBytes(4);
 | 
			
		||||
            let sx = sock.rQshift16();
 | 
			
		||||
            let sy = sock.rQshift16();
 | 
			
		||||
            let swidth = sock.rQshift16();
 | 
			
		||||
            let sheight = sock.rQshift16();
 | 
			
		||||
            display.fillRect(x + sx, y + sy, swidth, sheight, color);
 | 
			
		||||
 | 
			
		||||
            this._subrects--;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										393
									
								
								VM/novnc/core/decoders/tight.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,393 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import * as Log from '../util/logging.js';
 | 
			
		||||
import Inflator from "../inflator.js";
 | 
			
		||||
 | 
			
		||||
export default class TightDecoder {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._ctl = null;
 | 
			
		||||
        this._filter = null;
 | 
			
		||||
        this._numColors = 0;
 | 
			
		||||
        this._palette = new Uint8Array(1024);  // 256 * 4 (max palette size * max bytes-per-pixel)
 | 
			
		||||
        this._len = 0;
 | 
			
		||||
 | 
			
		||||
        this._zlibs = [];
 | 
			
		||||
        for (let i = 0; i < 4; i++) {
 | 
			
		||||
            this._zlibs[i] = new Inflator();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    decodeRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if (this._ctl === null) {
 | 
			
		||||
            if (sock.rQwait("TIGHT compression-control", 1)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._ctl = sock.rQshift8();
 | 
			
		||||
 | 
			
		||||
            // Reset streams if the server requests it
 | 
			
		||||
            for (let i = 0; i < 4; i++) {
 | 
			
		||||
                if ((this._ctl >> i) & 1) {
 | 
			
		||||
                    this._zlibs[i].reset();
 | 
			
		||||
                    Log.Info("Reset zlib stream " + i);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Figure out filter
 | 
			
		||||
            this._ctl = this._ctl >> 4;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let ret;
 | 
			
		||||
 | 
			
		||||
        if (this._ctl === 0x08) {
 | 
			
		||||
            ret = this._fillRect(x, y, width, height,
 | 
			
		||||
                                 sock, display, depth);
 | 
			
		||||
        } else if (this._ctl === 0x09) {
 | 
			
		||||
            ret = this._jpegRect(x, y, width, height,
 | 
			
		||||
                                 sock, display, depth);
 | 
			
		||||
        } else if (this._ctl === 0x0A) {
 | 
			
		||||
            ret = this._pngRect(x, y, width, height,
 | 
			
		||||
                                sock, display, depth);
 | 
			
		||||
        } else if ((this._ctl & 0x08) == 0) {
 | 
			
		||||
            ret = this._basicRect(this._ctl, x, y, width, height,
 | 
			
		||||
                                  sock, display, depth);
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new Error("Illegal tight compression received (ctl: " +
 | 
			
		||||
                                   this._ctl + ")");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ret) {
 | 
			
		||||
            this._ctl = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _fillRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if (sock.rQwait("TIGHT", 3)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let pixel = sock.rQshiftBytes(3);
 | 
			
		||||
        display.fillRect(x, y, width, height, pixel, false);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _jpegRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        let data = this._readData(sock);
 | 
			
		||||
        if (data === null) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display.imageRect(x, y, width, height, "image/jpeg", data);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _pngRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        throw new Error("PNG received in standard Tight rect");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _basicRect(ctl, x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if (this._filter === null) {
 | 
			
		||||
            if (ctl & 0x4) {
 | 
			
		||||
                if (sock.rQwait("TIGHT", 1)) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                this._filter = sock.rQshift8();
 | 
			
		||||
            } else {
 | 
			
		||||
                // Implicit CopyFilter
 | 
			
		||||
                this._filter = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let streamId = ctl & 0x3;
 | 
			
		||||
 | 
			
		||||
        let ret;
 | 
			
		||||
 | 
			
		||||
        switch (this._filter) {
 | 
			
		||||
            case 0: // CopyFilter
 | 
			
		||||
                ret = this._copyFilter(streamId, x, y, width, height,
 | 
			
		||||
                                       sock, display, depth);
 | 
			
		||||
                break;
 | 
			
		||||
            case 1: // PaletteFilter
 | 
			
		||||
                ret = this._paletteFilter(streamId, x, y, width, height,
 | 
			
		||||
                                          sock, display, depth);
 | 
			
		||||
                break;
 | 
			
		||||
            case 2: // GradientFilter
 | 
			
		||||
                ret = this._gradientFilter(streamId, x, y, width, height,
 | 
			
		||||
                                           sock, display, depth);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new Error("Illegal tight filter received (ctl: " +
 | 
			
		||||
                                       this._filter + ")");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ret) {
 | 
			
		||||
            this._filter = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _copyFilter(streamId, x, y, width, height, sock, display, depth) {
 | 
			
		||||
        const uncompressedSize = width * height * 3;
 | 
			
		||||
        let data;
 | 
			
		||||
 | 
			
		||||
        if (uncompressedSize === 0) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (uncompressedSize < 12) {
 | 
			
		||||
            if (sock.rQwait("TIGHT", uncompressedSize)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            data = sock.rQshiftBytes(uncompressedSize);
 | 
			
		||||
        } else {
 | 
			
		||||
            data = this._readData(sock);
 | 
			
		||||
            if (data === null) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._zlibs[streamId].setInput(data);
 | 
			
		||||
            data = this._zlibs[streamId].inflate(uncompressedSize);
 | 
			
		||||
            this._zlibs[streamId].setInput(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let rgbx = new Uint8Array(width * height * 4);
 | 
			
		||||
        for (let i = 0, j = 0; i < width * height * 4; i += 4, j += 3) {
 | 
			
		||||
            rgbx[i]     = data[j];
 | 
			
		||||
            rgbx[i + 1] = data[j + 1];
 | 
			
		||||
            rgbx[i + 2] = data[j + 2];
 | 
			
		||||
            rgbx[i + 3] = 255;  // Alpha
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display.blitImage(x, y, width, height, rgbx, 0, false);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _paletteFilter(streamId, x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if (this._numColors === 0) {
 | 
			
		||||
            if (sock.rQwait("TIGHT palette", 1)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const numColors = sock.rQpeek8() + 1;
 | 
			
		||||
            const paletteSize = numColors * 3;
 | 
			
		||||
 | 
			
		||||
            if (sock.rQwait("TIGHT palette", 1 + paletteSize)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._numColors = numColors;
 | 
			
		||||
            sock.rQskipBytes(1);
 | 
			
		||||
 | 
			
		||||
            sock.rQshiftTo(this._palette, paletteSize);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const bpp = (this._numColors <= 2) ? 1 : 8;
 | 
			
		||||
        const rowSize = Math.floor((width * bpp + 7) / 8);
 | 
			
		||||
        const uncompressedSize = rowSize * height;
 | 
			
		||||
 | 
			
		||||
        let data;
 | 
			
		||||
 | 
			
		||||
        if (uncompressedSize === 0) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (uncompressedSize < 12) {
 | 
			
		||||
            if (sock.rQwait("TIGHT", uncompressedSize)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            data = sock.rQshiftBytes(uncompressedSize);
 | 
			
		||||
        } else {
 | 
			
		||||
            data = this._readData(sock);
 | 
			
		||||
            if (data === null) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._zlibs[streamId].setInput(data);
 | 
			
		||||
            data = this._zlibs[streamId].inflate(uncompressedSize);
 | 
			
		||||
            this._zlibs[streamId].setInput(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Convert indexed (palette based) image data to RGB
 | 
			
		||||
        if (this._numColors == 2) {
 | 
			
		||||
            this._monoRect(x, y, width, height, data, this._palette, display);
 | 
			
		||||
        } else {
 | 
			
		||||
            this._paletteRect(x, y, width, height, data, this._palette, display);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._numColors = 0;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _monoRect(x, y, width, height, data, palette, display) {
 | 
			
		||||
        // Convert indexed (palette based) image data to RGB
 | 
			
		||||
        // TODO: reduce number of calculations inside loop
 | 
			
		||||
        const dest = this._getScratchBuffer(width * height * 4);
 | 
			
		||||
        const w = Math.floor((width + 7) / 8);
 | 
			
		||||
        const w1 = Math.floor(width / 8);
 | 
			
		||||
 | 
			
		||||
        for (let y = 0; y < height; y++) {
 | 
			
		||||
            let dp, sp, x;
 | 
			
		||||
            for (x = 0; x < w1; x++) {
 | 
			
		||||
                for (let b = 7; b >= 0; b--) {
 | 
			
		||||
                    dp = (y * width + x * 8 + 7 - b) * 4;
 | 
			
		||||
                    sp = (data[y * w + x] >> b & 1) * 3;
 | 
			
		||||
                    dest[dp]     = palette[sp];
 | 
			
		||||
                    dest[dp + 1] = palette[sp + 1];
 | 
			
		||||
                    dest[dp + 2] = palette[sp + 2];
 | 
			
		||||
                    dest[dp + 3] = 255;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (let b = 7; b >= 8 - width % 8; b--) {
 | 
			
		||||
                dp = (y * width + x * 8 + 7 - b) * 4;
 | 
			
		||||
                sp = (data[y * w + x] >> b & 1) * 3;
 | 
			
		||||
                dest[dp]     = palette[sp];
 | 
			
		||||
                dest[dp + 1] = palette[sp + 1];
 | 
			
		||||
                dest[dp + 2] = palette[sp + 2];
 | 
			
		||||
                dest[dp + 3] = 255;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display.blitImage(x, y, width, height, dest, 0, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _paletteRect(x, y, width, height, data, palette, display) {
 | 
			
		||||
        // Convert indexed (palette based) image data to RGB
 | 
			
		||||
        const dest = this._getScratchBuffer(width * height * 4);
 | 
			
		||||
        const total = width * height * 4;
 | 
			
		||||
        for (let i = 0, j = 0; i < total; i += 4, j++) {
 | 
			
		||||
            const sp = data[j] * 3;
 | 
			
		||||
            dest[i]     = palette[sp];
 | 
			
		||||
            dest[i + 1] = palette[sp + 1];
 | 
			
		||||
            dest[i + 2] = palette[sp + 2];
 | 
			
		||||
            dest[i + 3] = 255;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display.blitImage(x, y, width, height, dest, 0, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _gradientFilter(streamId, x, y, width, height, sock, display, depth) {
 | 
			
		||||
        // assume the TPIXEL is 3 bytes long
 | 
			
		||||
        const uncompressedSize = width * height * 3;
 | 
			
		||||
        let data;
 | 
			
		||||
 | 
			
		||||
        if (uncompressedSize === 0) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (uncompressedSize < 12) {
 | 
			
		||||
            if (sock.rQwait("TIGHT", uncompressedSize)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            data = sock.rQshiftBytes(uncompressedSize);
 | 
			
		||||
        } else {
 | 
			
		||||
            data = this._readData(sock);
 | 
			
		||||
            if (data === null) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._zlibs[streamId].setInput(data);
 | 
			
		||||
            data = this._zlibs[streamId].inflate(uncompressedSize);
 | 
			
		||||
            this._zlibs[streamId].setInput(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let rgbx = new Uint8Array(4 * width * height);
 | 
			
		||||
 | 
			
		||||
        let rgbxIndex = 0, dataIndex = 0;
 | 
			
		||||
        let left = new Uint8Array(3);
 | 
			
		||||
        for (let x = 0; x < width; x++) {
 | 
			
		||||
            for (let c = 0; c < 3; c++) {
 | 
			
		||||
                const prediction = left[c];
 | 
			
		||||
                const value = data[dataIndex++] + prediction;
 | 
			
		||||
                rgbx[rgbxIndex++] = value;
 | 
			
		||||
                left[c] = value;
 | 
			
		||||
            }
 | 
			
		||||
            rgbx[rgbxIndex++] = 255;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let upperIndex = 0;
 | 
			
		||||
        let upper = new Uint8Array(3),
 | 
			
		||||
            upperleft = new Uint8Array(3);
 | 
			
		||||
        for (let y = 1; y < height; y++) {
 | 
			
		||||
            left.fill(0);
 | 
			
		||||
            upperleft.fill(0);
 | 
			
		||||
            for (let x = 0; x < width; x++) {
 | 
			
		||||
                for (let c = 0; c < 3; c++) {
 | 
			
		||||
                    upper[c] = rgbx[upperIndex++];
 | 
			
		||||
                    let prediction = left[c] + upper[c] - upperleft[c];
 | 
			
		||||
                    if (prediction < 0) {
 | 
			
		||||
                        prediction = 0;
 | 
			
		||||
                    } else if (prediction > 255) {
 | 
			
		||||
                        prediction = 255;
 | 
			
		||||
                    }
 | 
			
		||||
                    const value = data[dataIndex++] + prediction;
 | 
			
		||||
                    rgbx[rgbxIndex++] = value;
 | 
			
		||||
                    upperleft[c] = upper[c];
 | 
			
		||||
                    left[c] = value;
 | 
			
		||||
                }
 | 
			
		||||
                rgbx[rgbxIndex++] = 255;
 | 
			
		||||
                upperIndex++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display.blitImage(x, y, width, height, rgbx, 0, false);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _readData(sock) {
 | 
			
		||||
        if (this._len === 0) {
 | 
			
		||||
            if (sock.rQwait("TIGHT", 3)) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let byte;
 | 
			
		||||
 | 
			
		||||
            byte = sock.rQshift8();
 | 
			
		||||
            this._len = byte & 0x7f;
 | 
			
		||||
            if (byte & 0x80) {
 | 
			
		||||
                byte = sock.rQshift8();
 | 
			
		||||
                this._len |= (byte & 0x7f) << 7;
 | 
			
		||||
                if (byte & 0x80) {
 | 
			
		||||
                    byte = sock.rQshift8();
 | 
			
		||||
                    this._len |= byte << 14;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sock.rQwait("TIGHT", this._len)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let data = sock.rQshiftBytes(this._len, false);
 | 
			
		||||
        this._len = 0;
 | 
			
		||||
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getScratchBuffer(size) {
 | 
			
		||||
        if (!this._scratchBuffer || (this._scratchBuffer.length < size)) {
 | 
			
		||||
            this._scratchBuffer = new Uint8Array(size);
 | 
			
		||||
        }
 | 
			
		||||
        return this._scratchBuffer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								VM/novnc/core/decoders/tightpng.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,27 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import TightDecoder from './tight.js';
 | 
			
		||||
 | 
			
		||||
export default class TightPNGDecoder extends TightDecoder {
 | 
			
		||||
    _pngRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        let data = this._readData(sock);
 | 
			
		||||
        if (data === null) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display.imageRect(x, y, width, height, "image/png", data);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _basicRect(ctl, x, y, width, height, sock, display, depth) {
 | 
			
		||||
        throw new Error("BasicCompression received in TightPNG rect");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										185
									
								
								VM/novnc/core/decoders/zrle.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,185 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2021 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import Inflate from "../inflator.js";
 | 
			
		||||
 | 
			
		||||
const ZRLE_TILE_WIDTH = 64;
 | 
			
		||||
const ZRLE_TILE_HEIGHT = 64;
 | 
			
		||||
 | 
			
		||||
export default class ZRLEDecoder {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._length = 0;
 | 
			
		||||
        this._inflator = new Inflate();
 | 
			
		||||
 | 
			
		||||
        this._pixelBuffer = new Uint8Array(ZRLE_TILE_WIDTH * ZRLE_TILE_HEIGHT * 4);
 | 
			
		||||
        this._tileBuffer = new Uint8Array(ZRLE_TILE_WIDTH * ZRLE_TILE_HEIGHT * 4);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    decodeRect(x, y, width, height, sock, display, depth) {
 | 
			
		||||
        if (this._length === 0) {
 | 
			
		||||
            if (sock.rQwait("ZLib data length", 4)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            this._length = sock.rQshift32();
 | 
			
		||||
        }
 | 
			
		||||
        if (sock.rQwait("Zlib data", this._length)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const data = sock.rQshiftBytes(this._length, false);
 | 
			
		||||
 | 
			
		||||
        this._inflator.setInput(data);
 | 
			
		||||
 | 
			
		||||
        for (let ty = y; ty < y + height; ty += ZRLE_TILE_HEIGHT) {
 | 
			
		||||
            let th = Math.min(ZRLE_TILE_HEIGHT, y + height - ty);
 | 
			
		||||
 | 
			
		||||
            for (let tx = x; tx < x + width; tx += ZRLE_TILE_WIDTH) {
 | 
			
		||||
                let tw = Math.min(ZRLE_TILE_WIDTH, x + width - tx);
 | 
			
		||||
 | 
			
		||||
                const tileSize = tw * th;
 | 
			
		||||
                const subencoding = this._inflator.inflate(1)[0];
 | 
			
		||||
                if (subencoding === 0) {
 | 
			
		||||
                    // raw data
 | 
			
		||||
                    const data = this._readPixels(tileSize);
 | 
			
		||||
                    display.blitImage(tx, ty, tw, th, data, 0, false);
 | 
			
		||||
                } else if (subencoding === 1) {
 | 
			
		||||
                    // solid
 | 
			
		||||
                    const background = this._readPixels(1);
 | 
			
		||||
                    display.fillRect(tx, ty, tw, th, [background[0], background[1], background[2]]);
 | 
			
		||||
                } else if (subencoding >= 2 && subencoding <= 16) {
 | 
			
		||||
                    const data = this._decodePaletteTile(subencoding, tileSize, tw, th);
 | 
			
		||||
                    display.blitImage(tx, ty, tw, th, data, 0, false);
 | 
			
		||||
                } else if (subencoding === 128) {
 | 
			
		||||
                    const data = this._decodeRLETile(tileSize);
 | 
			
		||||
                    display.blitImage(tx, ty, tw, th, data, 0, false);
 | 
			
		||||
                } else if (subencoding >= 130 && subencoding <= 255) {
 | 
			
		||||
                    const data = this._decodeRLEPaletteTile(subencoding - 128, tileSize);
 | 
			
		||||
                    display.blitImage(tx, ty, tw, th, data, 0, false);
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw new Error('Unknown subencoding: ' + subencoding);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this._length = 0;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getBitsPerPixelInPalette(paletteSize) {
 | 
			
		||||
        if (paletteSize <= 2) {
 | 
			
		||||
            return 1;
 | 
			
		||||
        } else if (paletteSize <= 4) {
 | 
			
		||||
            return 2;
 | 
			
		||||
        } else if (paletteSize <= 16) {
 | 
			
		||||
            return 4;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _readPixels(pixels) {
 | 
			
		||||
        let data = this._pixelBuffer;
 | 
			
		||||
        const buffer = this._inflator.inflate(3*pixels);
 | 
			
		||||
        for (let i = 0, j = 0; i < pixels*4; i += 4, j += 3) {
 | 
			
		||||
            data[i]     = buffer[j];
 | 
			
		||||
            data[i + 1] = buffer[j + 1];
 | 
			
		||||
            data[i + 2] = buffer[j + 2];
 | 
			
		||||
            data[i + 3] = 255;  // Add the Alpha
 | 
			
		||||
        }
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _decodePaletteTile(paletteSize, tileSize, tilew, tileh) {
 | 
			
		||||
        const data = this._tileBuffer;
 | 
			
		||||
        const palette = this._readPixels(paletteSize);
 | 
			
		||||
        const bitsPerPixel = this._getBitsPerPixelInPalette(paletteSize);
 | 
			
		||||
        const mask = (1 << bitsPerPixel) - 1;
 | 
			
		||||
 | 
			
		||||
        let offset = 0;
 | 
			
		||||
        let encoded = this._inflator.inflate(1)[0];
 | 
			
		||||
 | 
			
		||||
        for (let y=0; y<tileh; y++) {
 | 
			
		||||
            let shift = 8-bitsPerPixel;
 | 
			
		||||
            for (let x=0; x<tilew; x++) {
 | 
			
		||||
                if (shift<0) {
 | 
			
		||||
                    shift=8-bitsPerPixel;
 | 
			
		||||
                    encoded = this._inflator.inflate(1)[0];
 | 
			
		||||
                }
 | 
			
		||||
                let indexInPalette = (encoded>>shift) & mask;
 | 
			
		||||
 | 
			
		||||
                data[offset] = palette[indexInPalette * 4];
 | 
			
		||||
                data[offset + 1] = palette[indexInPalette * 4 + 1];
 | 
			
		||||
                data[offset + 2] = palette[indexInPalette * 4 + 2];
 | 
			
		||||
                data[offset + 3] = palette[indexInPalette * 4 + 3];
 | 
			
		||||
                offset += 4;
 | 
			
		||||
                shift-=bitsPerPixel;
 | 
			
		||||
            }
 | 
			
		||||
            if (shift<8-bitsPerPixel && y<tileh-1) {
 | 
			
		||||
                encoded =  this._inflator.inflate(1)[0];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _decodeRLETile(tileSize) {
 | 
			
		||||
        const data = this._tileBuffer;
 | 
			
		||||
        let i = 0;
 | 
			
		||||
        while (i < tileSize) {
 | 
			
		||||
            const pixel = this._readPixels(1);
 | 
			
		||||
            const length = this._readRLELength();
 | 
			
		||||
            for (let j = 0; j < length; j++) {
 | 
			
		||||
                data[i * 4] = pixel[0];
 | 
			
		||||
                data[i * 4 + 1] = pixel[1];
 | 
			
		||||
                data[i * 4 + 2] = pixel[2];
 | 
			
		||||
                data[i * 4 + 3] = pixel[3];
 | 
			
		||||
                i++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _decodeRLEPaletteTile(paletteSize, tileSize) {
 | 
			
		||||
        const data = this._tileBuffer;
 | 
			
		||||
 | 
			
		||||
        // palette
 | 
			
		||||
        const palette = this._readPixels(paletteSize);
 | 
			
		||||
 | 
			
		||||
        let offset = 0;
 | 
			
		||||
        while (offset < tileSize) {
 | 
			
		||||
            let indexInPalette = this._inflator.inflate(1)[0];
 | 
			
		||||
            let length = 1;
 | 
			
		||||
            if (indexInPalette >= 128) {
 | 
			
		||||
                indexInPalette -= 128;
 | 
			
		||||
                length = this._readRLELength();
 | 
			
		||||
            }
 | 
			
		||||
            if (indexInPalette > paletteSize) {
 | 
			
		||||
                throw new Error('Too big index in palette: ' + indexInPalette + ', palette size: ' + paletteSize);
 | 
			
		||||
            }
 | 
			
		||||
            if (offset + length > tileSize) {
 | 
			
		||||
                throw new Error('Too big rle length in palette mode: ' + length + ', allowed length is: ' + (tileSize - offset));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (let j = 0; j < length; j++) {
 | 
			
		||||
                data[offset * 4] = palette[indexInPalette * 4];
 | 
			
		||||
                data[offset * 4 + 1] = palette[indexInPalette * 4 + 1];
 | 
			
		||||
                data[offset * 4 + 2] = palette[indexInPalette * 4 + 2];
 | 
			
		||||
                data[offset * 4 + 3] = palette[indexInPalette * 4 + 3];
 | 
			
		||||
                offset++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _readRLELength() {
 | 
			
		||||
        let length = 0;
 | 
			
		||||
        let current = 0;
 | 
			
		||||
        do {
 | 
			
		||||
            current = this._inflator.inflate(1)[0];
 | 
			
		||||
            length += current;
 | 
			
		||||
        } while (current === 255);
 | 
			
		||||
        return length + 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								VM/novnc/core/deflator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2020 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { deflateInit, deflate } from "../vendor/pako/lib/zlib/deflate.js";
 | 
			
		||||
import { Z_FULL_FLUSH, Z_DEFAULT_COMPRESSION } from "../vendor/pako/lib/zlib/deflate.js";
 | 
			
		||||
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
 | 
			
		||||
 | 
			
		||||
export default class Deflator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.strm = new ZStream();
 | 
			
		||||
        this.chunkSize = 1024 * 10 * 10;
 | 
			
		||||
        this.outputBuffer = new Uint8Array(this.chunkSize);
 | 
			
		||||
 | 
			
		||||
        deflateInit(this.strm, Z_DEFAULT_COMPRESSION);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    deflate(inData) {
 | 
			
		||||
        /* eslint-disable camelcase */
 | 
			
		||||
        this.strm.input = inData;
 | 
			
		||||
        this.strm.avail_in = this.strm.input.length;
 | 
			
		||||
        this.strm.next_in = 0;
 | 
			
		||||
        this.strm.output = this.outputBuffer;
 | 
			
		||||
        this.strm.avail_out = this.chunkSize;
 | 
			
		||||
        this.strm.next_out = 0;
 | 
			
		||||
        /* eslint-enable camelcase */
 | 
			
		||||
 | 
			
		||||
        let lastRet = deflate(this.strm, Z_FULL_FLUSH);
 | 
			
		||||
        let outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
 | 
			
		||||
 | 
			
		||||
        if (lastRet < 0) {
 | 
			
		||||
            throw new Error("zlib deflate failed");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.strm.avail_in > 0) {
 | 
			
		||||
            // Read chunks until done
 | 
			
		||||
 | 
			
		||||
            let chunks = [outData];
 | 
			
		||||
            let totalLen = outData.length;
 | 
			
		||||
            do {
 | 
			
		||||
                /* eslint-disable camelcase */
 | 
			
		||||
                this.strm.output = new Uint8Array(this.chunkSize);
 | 
			
		||||
                this.strm.next_out = 0;
 | 
			
		||||
                this.strm.avail_out = this.chunkSize;
 | 
			
		||||
                /* eslint-enable camelcase */
 | 
			
		||||
 | 
			
		||||
                lastRet = deflate(this.strm, Z_FULL_FLUSH);
 | 
			
		||||
 | 
			
		||||
                if (lastRet < 0) {
 | 
			
		||||
                    throw new Error("zlib deflate failed");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let chunk = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
 | 
			
		||||
                totalLen += chunk.length;
 | 
			
		||||
                chunks.push(chunk);
 | 
			
		||||
            } while (this.strm.avail_in > 0);
 | 
			
		||||
 | 
			
		||||
            // Combine chunks into a single data
 | 
			
		||||
 | 
			
		||||
            let newData = new Uint8Array(totalLen);
 | 
			
		||||
            let offset = 0;
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < chunks.length; i++) {
 | 
			
		||||
                newData.set(chunks[i], offset);
 | 
			
		||||
                offset += chunks[i].length;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            outData = newData;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* eslint-disable camelcase */
 | 
			
		||||
        this.strm.input = null;
 | 
			
		||||
        this.strm.avail_in = 0;
 | 
			
		||||
        this.strm.next_in = 0;
 | 
			
		||||
        /* eslint-enable camelcase */
 | 
			
		||||
 | 
			
		||||
        return outData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										528
									
								
								VM/novnc/core/display.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,528 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import * as Log from './util/logging.js';
 | 
			
		||||
import Base64 from "./base64.js";
 | 
			
		||||
import { toSigned32bit } from './util/int.js';
 | 
			
		||||
 | 
			
		||||
export default class Display {
 | 
			
		||||
    constructor(target) {
 | 
			
		||||
        this._drawCtx = null;
 | 
			
		||||
 | 
			
		||||
        this._renderQ = [];  // queue drawing actions for in-oder rendering
 | 
			
		||||
        this._flushPromise = null;
 | 
			
		||||
 | 
			
		||||
        // the full frame buffer (logical canvas) size
 | 
			
		||||
        this._fbWidth = 0;
 | 
			
		||||
        this._fbHeight = 0;
 | 
			
		||||
 | 
			
		||||
        this._prevDrawStyle = "";
 | 
			
		||||
 | 
			
		||||
        Log.Debug(">> Display.constructor");
 | 
			
		||||
 | 
			
		||||
        // The visible canvas
 | 
			
		||||
        this._target = target;
 | 
			
		||||
 | 
			
		||||
        if (!this._target) {
 | 
			
		||||
            throw new Error("Target must be set");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (typeof this._target === 'string') {
 | 
			
		||||
            throw new Error('target must be a DOM element');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this._target.getContext) {
 | 
			
		||||
            throw new Error("no getContext method");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._targetCtx = this._target.getContext('2d');
 | 
			
		||||
 | 
			
		||||
        // the visible canvas viewport (i.e. what actually gets seen)
 | 
			
		||||
        this._viewportLoc = { 'x': 0, 'y': 0, 'w': this._target.width, 'h': this._target.height };
 | 
			
		||||
 | 
			
		||||
        // The hidden canvas, where we do the actual rendering
 | 
			
		||||
        this._backbuffer = document.createElement('canvas');
 | 
			
		||||
        this._drawCtx = this._backbuffer.getContext('2d');
 | 
			
		||||
 | 
			
		||||
        this._damageBounds = { left: 0, top: 0,
 | 
			
		||||
                               right: this._backbuffer.width,
 | 
			
		||||
                               bottom: this._backbuffer.height };
 | 
			
		||||
 | 
			
		||||
        Log.Debug("User Agent: " + navigator.userAgent);
 | 
			
		||||
 | 
			
		||||
        Log.Debug("<< Display.constructor");
 | 
			
		||||
 | 
			
		||||
        // ===== PROPERTIES =====
 | 
			
		||||
 | 
			
		||||
        this._scale = 1.0;
 | 
			
		||||
        this._clipViewport = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ===== PROPERTIES =====
 | 
			
		||||
 | 
			
		||||
    get scale() { return this._scale; }
 | 
			
		||||
    set scale(scale) {
 | 
			
		||||
        this._rescale(scale);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get clipViewport() { return this._clipViewport; }
 | 
			
		||||
    set clipViewport(viewport) {
 | 
			
		||||
        this._clipViewport = viewport;
 | 
			
		||||
        // May need to readjust the viewport dimensions
 | 
			
		||||
        const vp = this._viewportLoc;
 | 
			
		||||
        this.viewportChangeSize(vp.w, vp.h);
 | 
			
		||||
        this.viewportChangePos(0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get width() {
 | 
			
		||||
        return this._fbWidth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get height() {
 | 
			
		||||
        return this._fbHeight;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ===== PUBLIC METHODS =====
 | 
			
		||||
 | 
			
		||||
    viewportChangePos(deltaX, deltaY) {
 | 
			
		||||
        const vp = this._viewportLoc;
 | 
			
		||||
        deltaX = Math.floor(deltaX);
 | 
			
		||||
        deltaY = Math.floor(deltaY);
 | 
			
		||||
 | 
			
		||||
        if (!this._clipViewport) {
 | 
			
		||||
            deltaX = -vp.w;  // clamped later of out of bounds
 | 
			
		||||
            deltaY = -vp.h;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const vx2 = vp.x + vp.w - 1;
 | 
			
		||||
        const vy2 = vp.y + vp.h - 1;
 | 
			
		||||
 | 
			
		||||
        // Position change
 | 
			
		||||
 | 
			
		||||
        if (deltaX < 0 && vp.x + deltaX < 0) {
 | 
			
		||||
            deltaX = -vp.x;
 | 
			
		||||
        }
 | 
			
		||||
        if (vx2 + deltaX >= this._fbWidth) {
 | 
			
		||||
            deltaX -= vx2 + deltaX - this._fbWidth + 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (vp.y + deltaY < 0) {
 | 
			
		||||
            deltaY = -vp.y;
 | 
			
		||||
        }
 | 
			
		||||
        if (vy2 + deltaY >= this._fbHeight) {
 | 
			
		||||
            deltaY -= (vy2 + deltaY - this._fbHeight + 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (deltaX === 0 && deltaY === 0) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Log.Debug("viewportChange deltaX: " + deltaX + ", deltaY: " + deltaY);
 | 
			
		||||
 | 
			
		||||
        vp.x += deltaX;
 | 
			
		||||
        vp.y += deltaY;
 | 
			
		||||
 | 
			
		||||
        this._damage(vp.x, vp.y, vp.w, vp.h);
 | 
			
		||||
 | 
			
		||||
        this.flip();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    viewportChangeSize(width, height) {
 | 
			
		||||
 | 
			
		||||
        if (!this._clipViewport ||
 | 
			
		||||
            typeof(width) === "undefined" ||
 | 
			
		||||
            typeof(height) === "undefined") {
 | 
			
		||||
 | 
			
		||||
            Log.Debug("Setting viewport to full display region");
 | 
			
		||||
            width = this._fbWidth;
 | 
			
		||||
            height = this._fbHeight;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        width = Math.floor(width);
 | 
			
		||||
        height = Math.floor(height);
 | 
			
		||||
 | 
			
		||||
        if (width > this._fbWidth) {
 | 
			
		||||
            width = this._fbWidth;
 | 
			
		||||
        }
 | 
			
		||||
        if (height > this._fbHeight) {
 | 
			
		||||
            height = this._fbHeight;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const vp = this._viewportLoc;
 | 
			
		||||
        if (vp.w !== width || vp.h !== height) {
 | 
			
		||||
            vp.w = width;
 | 
			
		||||
            vp.h = height;
 | 
			
		||||
 | 
			
		||||
            const canvas = this._target;
 | 
			
		||||
            canvas.width = width;
 | 
			
		||||
            canvas.height = height;
 | 
			
		||||
 | 
			
		||||
            // The position might need to be updated if we've grown
 | 
			
		||||
            this.viewportChangePos(0, 0);
 | 
			
		||||
 | 
			
		||||
            this._damage(vp.x, vp.y, vp.w, vp.h);
 | 
			
		||||
            this.flip();
 | 
			
		||||
 | 
			
		||||
            // Update the visible size of the target canvas
 | 
			
		||||
            this._rescale(this._scale);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    absX(x) {
 | 
			
		||||
        if (this._scale === 0) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        return toSigned32bit(x / this._scale + this._viewportLoc.x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    absY(y) {
 | 
			
		||||
        if (this._scale === 0) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        return toSigned32bit(y / this._scale + this._viewportLoc.y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    resize(width, height) {
 | 
			
		||||
        this._prevDrawStyle = "";
 | 
			
		||||
 | 
			
		||||
        this._fbWidth = width;
 | 
			
		||||
        this._fbHeight = height;
 | 
			
		||||
 | 
			
		||||
        const canvas = this._backbuffer;
 | 
			
		||||
        if (canvas.width !== width || canvas.height !== height) {
 | 
			
		||||
 | 
			
		||||
            // We have to save the canvas data since changing the size will clear it
 | 
			
		||||
            let saveImg = null;
 | 
			
		||||
            if (canvas.width > 0 && canvas.height > 0) {
 | 
			
		||||
                saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (canvas.width !== width) {
 | 
			
		||||
                canvas.width = width;
 | 
			
		||||
            }
 | 
			
		||||
            if (canvas.height !== height) {
 | 
			
		||||
                canvas.height = height;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (saveImg) {
 | 
			
		||||
                this._drawCtx.putImageData(saveImg, 0, 0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Readjust the viewport as it may be incorrectly sized
 | 
			
		||||
        // and positioned
 | 
			
		||||
        const vp = this._viewportLoc;
 | 
			
		||||
        this.viewportChangeSize(vp.w, vp.h);
 | 
			
		||||
        this.viewportChangePos(0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getImageData() {
 | 
			
		||||
        return this._drawCtx.getImageData(0, 0, this.width, this.height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    toDataURL(type, encoderOptions) {
 | 
			
		||||
        return this._backbuffer.toDataURL(type, encoderOptions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    toBlob(callback, type, quality) {
 | 
			
		||||
        return this._backbuffer.toBlob(callback, type, quality);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Track what parts of the visible canvas that need updating
 | 
			
		||||
    _damage(x, y, w, h) {
 | 
			
		||||
        if (x < this._damageBounds.left) {
 | 
			
		||||
            this._damageBounds.left = x;
 | 
			
		||||
        }
 | 
			
		||||
        if (y < this._damageBounds.top) {
 | 
			
		||||
            this._damageBounds.top = y;
 | 
			
		||||
        }
 | 
			
		||||
        if ((x + w) > this._damageBounds.right) {
 | 
			
		||||
            this._damageBounds.right = x + w;
 | 
			
		||||
        }
 | 
			
		||||
        if ((y + h) > this._damageBounds.bottom) {
 | 
			
		||||
            this._damageBounds.bottom = y + h;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update the visible canvas with the contents of the
 | 
			
		||||
    // rendering canvas
 | 
			
		||||
    flip(fromQueue) {
 | 
			
		||||
        if (this._renderQ.length !== 0 && !fromQueue) {
 | 
			
		||||
            this._renderQPush({
 | 
			
		||||
                'type': 'flip'
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            let x = this._damageBounds.left;
 | 
			
		||||
            let y = this._damageBounds.top;
 | 
			
		||||
            let w = this._damageBounds.right - x;
 | 
			
		||||
            let h = this._damageBounds.bottom - y;
 | 
			
		||||
 | 
			
		||||
            let vx = x - this._viewportLoc.x;
 | 
			
		||||
            let vy = y - this._viewportLoc.y;
 | 
			
		||||
 | 
			
		||||
            if (vx < 0) {
 | 
			
		||||
                w += vx;
 | 
			
		||||
                x -= vx;
 | 
			
		||||
                vx = 0;
 | 
			
		||||
            }
 | 
			
		||||
            if (vy < 0) {
 | 
			
		||||
                h += vy;
 | 
			
		||||
                y -= vy;
 | 
			
		||||
                vy = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ((vx + w) > this._viewportLoc.w) {
 | 
			
		||||
                w = this._viewportLoc.w - vx;
 | 
			
		||||
            }
 | 
			
		||||
            if ((vy + h) > this._viewportLoc.h) {
 | 
			
		||||
                h = this._viewportLoc.h - vy;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ((w > 0) && (h > 0)) {
 | 
			
		||||
                // FIXME: We may need to disable image smoothing here
 | 
			
		||||
                //        as well (see copyImage()), but we haven't
 | 
			
		||||
                //        noticed any problem yet.
 | 
			
		||||
                this._targetCtx.drawImage(this._backbuffer,
 | 
			
		||||
                                          x, y, w, h,
 | 
			
		||||
                                          vx, vy, w, h);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._damageBounds.left = this._damageBounds.top = 65535;
 | 
			
		||||
            this._damageBounds.right = this._damageBounds.bottom = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pending() {
 | 
			
		||||
        return this._renderQ.length > 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    flush() {
 | 
			
		||||
        if (this._renderQ.length === 0) {
 | 
			
		||||
            return Promise.resolve();
 | 
			
		||||
        } else {
 | 
			
		||||
            if (this._flushPromise === null) {
 | 
			
		||||
                this._flushPromise = new Promise((resolve) => {
 | 
			
		||||
                    this._flushResolve = resolve;
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            return this._flushPromise;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fillRect(x, y, width, height, color, fromQueue) {
 | 
			
		||||
        if (this._renderQ.length !== 0 && !fromQueue) {
 | 
			
		||||
            this._renderQPush({
 | 
			
		||||
                'type': 'fill',
 | 
			
		||||
                'x': x,
 | 
			
		||||
                'y': y,
 | 
			
		||||
                'width': width,
 | 
			
		||||
                'height': height,
 | 
			
		||||
                'color': color
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            this._setFillColor(color);
 | 
			
		||||
            this._drawCtx.fillRect(x, y, width, height);
 | 
			
		||||
            this._damage(x, y, width, height);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    copyImage(oldX, oldY, newX, newY, w, h, fromQueue) {
 | 
			
		||||
        if (this._renderQ.length !== 0 && !fromQueue) {
 | 
			
		||||
            this._renderQPush({
 | 
			
		||||
                'type': 'copy',
 | 
			
		||||
                'oldX': oldX,
 | 
			
		||||
                'oldY': oldY,
 | 
			
		||||
                'x': newX,
 | 
			
		||||
                'y': newY,
 | 
			
		||||
                'width': w,
 | 
			
		||||
                'height': h,
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            // Due to this bug among others [1] we need to disable the image-smoothing to
 | 
			
		||||
            // avoid getting a blur effect when copying data.
 | 
			
		||||
            //
 | 
			
		||||
            // 1. https://bugzilla.mozilla.org/show_bug.cgi?id=1194719
 | 
			
		||||
            //
 | 
			
		||||
            // We need to set these every time since all properties are reset
 | 
			
		||||
            // when the the size is changed
 | 
			
		||||
            this._drawCtx.mozImageSmoothingEnabled = false;
 | 
			
		||||
            this._drawCtx.webkitImageSmoothingEnabled = false;
 | 
			
		||||
            this._drawCtx.msImageSmoothingEnabled = false;
 | 
			
		||||
            this._drawCtx.imageSmoothingEnabled = false;
 | 
			
		||||
 | 
			
		||||
            this._drawCtx.drawImage(this._backbuffer,
 | 
			
		||||
                                    oldX, oldY, w, h,
 | 
			
		||||
                                    newX, newY, w, h);
 | 
			
		||||
            this._damage(newX, newY, w, h);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    imageRect(x, y, width, height, mime, arr) {
 | 
			
		||||
        /* The internal logic cannot handle empty images, so bail early */
 | 
			
		||||
        if ((width === 0) || (height === 0)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const img = new Image();
 | 
			
		||||
        img.src = "data: " + mime + ";base64," + Base64.encode(arr);
 | 
			
		||||
 | 
			
		||||
        this._renderQPush({
 | 
			
		||||
            'type': 'img',
 | 
			
		||||
            'img': img,
 | 
			
		||||
            'x': x,
 | 
			
		||||
            'y': y,
 | 
			
		||||
            'width': width,
 | 
			
		||||
            'height': height
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    blitImage(x, y, width, height, arr, offset, fromQueue) {
 | 
			
		||||
        if (this._renderQ.length !== 0 && !fromQueue) {
 | 
			
		||||
            // NB(directxman12): it's technically more performant here to use preallocated arrays,
 | 
			
		||||
            // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
 | 
			
		||||
            // this probably isn't getting called *nearly* as much
 | 
			
		||||
            const newArr = new Uint8Array(width * height * 4);
 | 
			
		||||
            newArr.set(new Uint8Array(arr.buffer, 0, newArr.length));
 | 
			
		||||
            this._renderQPush({
 | 
			
		||||
                'type': 'blit',
 | 
			
		||||
                'data': newArr,
 | 
			
		||||
                'x': x,
 | 
			
		||||
                'y': y,
 | 
			
		||||
                'width': width,
 | 
			
		||||
                'height': height,
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            // NB(directxman12): arr must be an Type Array view
 | 
			
		||||
            let data = new Uint8ClampedArray(arr.buffer,
 | 
			
		||||
                                             arr.byteOffset + offset,
 | 
			
		||||
                                             width * height * 4);
 | 
			
		||||
            let img = new ImageData(data, width, height);
 | 
			
		||||
            this._drawCtx.putImageData(img, x, y);
 | 
			
		||||
            this._damage(x, y, width, height);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    drawImage(img, x, y) {
 | 
			
		||||
        this._drawCtx.drawImage(img, x, y);
 | 
			
		||||
        this._damage(x, y, img.width, img.height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    autoscale(containerWidth, containerHeight) {
 | 
			
		||||
        let scaleRatio;
 | 
			
		||||
 | 
			
		||||
        if (containerWidth === 0 || containerHeight === 0) {
 | 
			
		||||
            scaleRatio = 0;
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            const vp = this._viewportLoc;
 | 
			
		||||
            const targetAspectRatio = containerWidth / containerHeight;
 | 
			
		||||
            const fbAspectRatio = vp.w / vp.h;
 | 
			
		||||
 | 
			
		||||
            if (fbAspectRatio >= targetAspectRatio) {
 | 
			
		||||
                scaleRatio = containerWidth / vp.w;
 | 
			
		||||
            } else {
 | 
			
		||||
                scaleRatio = containerHeight / vp.h;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._rescale(scaleRatio);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ===== PRIVATE METHODS =====
 | 
			
		||||
 | 
			
		||||
    _rescale(factor) {
 | 
			
		||||
        this._scale = factor;
 | 
			
		||||
        const vp = this._viewportLoc;
 | 
			
		||||
 | 
			
		||||
        // NB(directxman12): If you set the width directly, or set the
 | 
			
		||||
        //                   style width to a number, the canvas is cleared.
 | 
			
		||||
        //                   However, if you set the style width to a string
 | 
			
		||||
        //                   ('NNNpx'), the canvas is scaled without clearing.
 | 
			
		||||
        const width = factor * vp.w + 'px';
 | 
			
		||||
        const height = factor * vp.h + 'px';
 | 
			
		||||
 | 
			
		||||
        if ((this._target.style.width !== width) ||
 | 
			
		||||
            (this._target.style.height !== height)) {
 | 
			
		||||
            this._target.style.width = width;
 | 
			
		||||
            this._target.style.height = height;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setFillColor(color) {
 | 
			
		||||
        const newStyle = 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')';
 | 
			
		||||
        if (newStyle !== this._prevDrawStyle) {
 | 
			
		||||
            this._drawCtx.fillStyle = newStyle;
 | 
			
		||||
            this._prevDrawStyle = newStyle;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _renderQPush(action) {
 | 
			
		||||
        this._renderQ.push(action);
 | 
			
		||||
        if (this._renderQ.length === 1) {
 | 
			
		||||
            // If this can be rendered immediately it will be, otherwise
 | 
			
		||||
            // the scanner will wait for the relevant event
 | 
			
		||||
            this._scanRenderQ();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _resumeRenderQ() {
 | 
			
		||||
        // "this" is the object that is ready, not the
 | 
			
		||||
        // display object
 | 
			
		||||
        this.removeEventListener('load', this._noVNCDisplay._resumeRenderQ);
 | 
			
		||||
        this._noVNCDisplay._scanRenderQ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _scanRenderQ() {
 | 
			
		||||
        let ready = true;
 | 
			
		||||
        while (ready && this._renderQ.length > 0) {
 | 
			
		||||
            const a = this._renderQ[0];
 | 
			
		||||
            switch (a.type) {
 | 
			
		||||
                case 'flip':
 | 
			
		||||
                    this.flip(true);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'copy':
 | 
			
		||||
                    this.copyImage(a.oldX, a.oldY, a.x, a.y, a.width, a.height, true);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'fill':
 | 
			
		||||
                    this.fillRect(a.x, a.y, a.width, a.height, a.color, true);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'blit':
 | 
			
		||||
                    this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'img':
 | 
			
		||||
                    if (a.img.complete) {
 | 
			
		||||
                        if (a.img.width !== a.width || a.img.height !== a.height) {
 | 
			
		||||
                            Log.Error("Decoded image has incorrect dimensions. Got " +
 | 
			
		||||
                                      a.img.width + "x" + a.img.height + ". Expected " +
 | 
			
		||||
                                      a.width + "x" + a.height + ".");
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        this.drawImage(a.img, a.x, a.y);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        a.img._noVNCDisplay = this;
 | 
			
		||||
                        a.img.addEventListener('load', this._resumeRenderQ);
 | 
			
		||||
                        // We need to wait for this image to 'load'
 | 
			
		||||
                        // to keep things in-order
 | 
			
		||||
                        ready = false;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (ready) {
 | 
			
		||||
                this._renderQ.shift();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._renderQ.length === 0 &&
 | 
			
		||||
            this._flushPromise !== null) {
 | 
			
		||||
            this._flushResolve();
 | 
			
		||||
            this._flushPromise = null;
 | 
			
		||||
            this._flushResolve = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								VM/novnc/core/encodings.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,49 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2019 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export const encodings = {
 | 
			
		||||
    encodingRaw: 0,
 | 
			
		||||
    encodingCopyRect: 1,
 | 
			
		||||
    encodingRRE: 2,
 | 
			
		||||
    encodingHextile: 5,
 | 
			
		||||
    encodingTight: 7,
 | 
			
		||||
    encodingZRLE: 16,
 | 
			
		||||
    encodingTightPNG: -260,
 | 
			
		||||
    encodingJPEG: 21,
 | 
			
		||||
 | 
			
		||||
    pseudoEncodingQualityLevel9: -23,
 | 
			
		||||
    pseudoEncodingQualityLevel0: -32,
 | 
			
		||||
    pseudoEncodingDesktopSize: -223,
 | 
			
		||||
    pseudoEncodingLastRect: -224,
 | 
			
		||||
    pseudoEncodingCursor: -239,
 | 
			
		||||
    pseudoEncodingQEMUExtendedKeyEvent: -258,
 | 
			
		||||
    pseudoEncodingQEMULedEvent: -261,
 | 
			
		||||
    pseudoEncodingDesktopName: -307,
 | 
			
		||||
    pseudoEncodingExtendedDesktopSize: -308,
 | 
			
		||||
    pseudoEncodingXvp: -309,
 | 
			
		||||
    pseudoEncodingFence: -312,
 | 
			
		||||
    pseudoEncodingContinuousUpdates: -313,
 | 
			
		||||
    pseudoEncodingCompressLevel9: -247,
 | 
			
		||||
    pseudoEncodingCompressLevel0: -256,
 | 
			
		||||
    pseudoEncodingVMwareCursor: 0x574d5664,
 | 
			
		||||
    pseudoEncodingExtendedClipboard: 0xc0a1e5ce
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function encodingName(num) {
 | 
			
		||||
    switch (num) {
 | 
			
		||||
        case encodings.encodingRaw:      return "Raw";
 | 
			
		||||
        case encodings.encodingCopyRect: return "CopyRect";
 | 
			
		||||
        case encodings.encodingRRE:      return "RRE";
 | 
			
		||||
        case encodings.encodingHextile:  return "Hextile";
 | 
			
		||||
        case encodings.encodingTight:    return "Tight";
 | 
			
		||||
        case encodings.encodingZRLE:     return "ZRLE";
 | 
			
		||||
        case encodings.encodingTightPNG: return "TightPNG";
 | 
			
		||||
        case encodings.encodingJPEG:     return "JPEG";
 | 
			
		||||
        default:                         return "[unknown encoding " + num + "]";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								VM/novnc/core/inflator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,65 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2020 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 (see LICENSE.txt)
 | 
			
		||||
 *
 | 
			
		||||
 * See README.md for usage and integration instructions.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { inflateInit, inflate, inflateReset } from "../vendor/pako/lib/zlib/inflate.js";
 | 
			
		||||
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
 | 
			
		||||
 | 
			
		||||
export default class Inflate {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.strm = new ZStream();
 | 
			
		||||
        this.chunkSize = 1024 * 10 * 10;
 | 
			
		||||
        this.strm.output = new Uint8Array(this.chunkSize);
 | 
			
		||||
 | 
			
		||||
        inflateInit(this.strm);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setInput(data) {
 | 
			
		||||
        if (!data) {
 | 
			
		||||
            //FIXME: flush remaining data.
 | 
			
		||||
            /* eslint-disable camelcase */
 | 
			
		||||
            this.strm.input = null;
 | 
			
		||||
            this.strm.avail_in = 0;
 | 
			
		||||
            this.strm.next_in = 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            this.strm.input = data;
 | 
			
		||||
            this.strm.avail_in = this.strm.input.length;
 | 
			
		||||
            this.strm.next_in = 0;
 | 
			
		||||
            /* eslint-enable camelcase */
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inflate(expected) {
 | 
			
		||||
        // resize our output buffer if it's too small
 | 
			
		||||
        // (we could just use multiple chunks, but that would cause an extra
 | 
			
		||||
        // allocation each time to flatten the chunks)
 | 
			
		||||
        if (expected > this.chunkSize) {
 | 
			
		||||
            this.chunkSize = expected;
 | 
			
		||||
            this.strm.output = new Uint8Array(this.chunkSize);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* eslint-disable camelcase */
 | 
			
		||||
        this.strm.next_out = 0;
 | 
			
		||||
        this.strm.avail_out = expected;
 | 
			
		||||
        /* eslint-enable camelcase */
 | 
			
		||||
 | 
			
		||||
        let ret = inflate(this.strm, 0); // Flush argument not used.
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            throw new Error("zlib inflate failed");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.strm.next_out != expected) {
 | 
			
		||||
            throw new Error("Incomplete zlib block");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reset() {
 | 
			
		||||
        inflateReset(this.strm);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										311
									
								
								VM/novnc/core/input/domkeytable.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,311 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2018 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import KeyTable from "./keysym.js";
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Mapping between HTML key values and VNC/X11 keysyms for "special"
 | 
			
		||||
 * keys that cannot be handled via their Unicode codepoint.
 | 
			
		||||
 *
 | 
			
		||||
 * See https://www.w3.org/TR/uievents-key/ for possible values.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const DOMKeyTable = {};
 | 
			
		||||
 | 
			
		||||
function addStandard(key, standard) {
 | 
			
		||||
    if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
 | 
			
		||||
    if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\"");
 | 
			
		||||
    DOMKeyTable[key] = [standard, standard, standard, standard];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addLeftRight(key, left, right) {
 | 
			
		||||
    if (left === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
 | 
			
		||||
    if (right === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
 | 
			
		||||
    if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\"");
 | 
			
		||||
    DOMKeyTable[key] = [left, left, right, left];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addNumpad(key, standard, numpad) {
 | 
			
		||||
    if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
 | 
			
		||||
    if (numpad === undefined) throw new Error("Undefined keysym for key \"" + key + "\"");
 | 
			
		||||
    if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\"");
 | 
			
		||||
    DOMKeyTable[key] = [standard, standard, standard, numpad];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 3.2. Modifier Keys
 | 
			
		||||
 | 
			
		||||
addLeftRight("Alt", KeyTable.XK_Alt_L, KeyTable.XK_Alt_R);
 | 
			
		||||
addStandard("AltGraph", KeyTable.XK_ISO_Level3_Shift);
 | 
			
		||||
addStandard("CapsLock", KeyTable.XK_Caps_Lock);
 | 
			
		||||
addLeftRight("Control", KeyTable.XK_Control_L, KeyTable.XK_Control_R);
 | 
			
		||||
// - Fn
 | 
			
		||||
// - FnLock
 | 
			
		||||
addLeftRight("Meta", KeyTable.XK_Super_L, KeyTable.XK_Super_R);
 | 
			
		||||
addStandard("NumLock", KeyTable.XK_Num_Lock);
 | 
			
		||||
addStandard("ScrollLock", KeyTable.XK_Scroll_Lock);
 | 
			
		||||
addLeftRight("Shift", KeyTable.XK_Shift_L, KeyTable.XK_Shift_R);
 | 
			
		||||
// - Symbol
 | 
			
		||||
// - SymbolLock
 | 
			
		||||
// - Hyper
 | 
			
		||||
// - Super
 | 
			
		||||
 | 
			
		||||
// 3.3. Whitespace Keys
 | 
			
		||||
 | 
			
		||||
addNumpad("Enter", KeyTable.XK_Return, KeyTable.XK_KP_Enter);
 | 
			
		||||
addStandard("Tab", KeyTable.XK_Tab);
 | 
			
		||||
addNumpad(" ", KeyTable.XK_space, KeyTable.XK_KP_Space);
 | 
			
		||||
 | 
			
		||||
// 3.4. Navigation Keys
 | 
			
		||||
 | 
			
		||||
addNumpad("ArrowDown", KeyTable.XK_Down, KeyTable.XK_KP_Down);
 | 
			
		||||
addNumpad("ArrowLeft", KeyTable.XK_Left, KeyTable.XK_KP_Left);
 | 
			
		||||
addNumpad("ArrowRight", KeyTable.XK_Right, KeyTable.XK_KP_Right);
 | 
			
		||||
addNumpad("ArrowUp", KeyTable.XK_Up, KeyTable.XK_KP_Up);
 | 
			
		||||
addNumpad("End", KeyTable.XK_End, KeyTable.XK_KP_End);
 | 
			
		||||
addNumpad("Home", KeyTable.XK_Home, KeyTable.XK_KP_Home);
 | 
			
		||||
addNumpad("PageDown", KeyTable.XK_Next, KeyTable.XK_KP_Next);
 | 
			
		||||
addNumpad("PageUp", KeyTable.XK_Prior, KeyTable.XK_KP_Prior);
 | 
			
		||||
 | 
			
		||||
// 3.5. Editing Keys
 | 
			
		||||
 | 
			
		||||
addStandard("Backspace", KeyTable.XK_BackSpace);
 | 
			
		||||
// Browsers send "Clear" for the numpad 5 without NumLock because
 | 
			
		||||
// Windows uses VK_Clear for that key. But Unix expects KP_Begin for
 | 
			
		||||
// that scenario.
 | 
			
		||||
addNumpad("Clear", KeyTable.XK_Clear, KeyTable.XK_KP_Begin);
 | 
			
		||||
addStandard("Copy", KeyTable.XF86XK_Copy);
 | 
			
		||||
// - CrSel
 | 
			
		||||
addStandard("Cut", KeyTable.XF86XK_Cut);
 | 
			
		||||
addNumpad("Delete", KeyTable.XK_Delete, KeyTable.XK_KP_Delete);
 | 
			
		||||
// - EraseEof
 | 
			
		||||
// - ExSel
 | 
			
		||||
addNumpad("Insert", KeyTable.XK_Insert, KeyTable.XK_KP_Insert);
 | 
			
		||||
addStandard("Paste", KeyTable.XF86XK_Paste);
 | 
			
		||||
addStandard("Redo", KeyTable.XK_Redo);
 | 
			
		||||
addStandard("Undo", KeyTable.XK_Undo);
 | 
			
		||||
 | 
			
		||||
// 3.6. UI Keys
 | 
			
		||||
 | 
			
		||||
// - Accept
 | 
			
		||||
// - Again (could just be XK_Redo)
 | 
			
		||||
// - Attn
 | 
			
		||||
addStandard("Cancel", KeyTable.XK_Cancel);
 | 
			
		||||
addStandard("ContextMenu", KeyTable.XK_Menu);
 | 
			
		||||
addStandard("Escape", KeyTable.XK_Escape);
 | 
			
		||||
addStandard("Execute", KeyTable.XK_Execute);
 | 
			
		||||
addStandard("Find", KeyTable.XK_Find);
 | 
			
		||||
addStandard("Help", KeyTable.XK_Help);
 | 
			
		||||
addStandard("Pause", KeyTable.XK_Pause);
 | 
			
		||||
// - Play
 | 
			
		||||
// - Props
 | 
			
		||||
addStandard("Select", KeyTable.XK_Select);
 | 
			
		||||
addStandard("ZoomIn", KeyTable.XF86XK_ZoomIn);
 | 
			
		||||
addStandard("ZoomOut", KeyTable.XF86XK_ZoomOut);
 | 
			
		||||
 | 
			
		||||
// 3.7. Device Keys
 | 
			
		||||
 | 
			
		||||
addStandard("BrightnessDown", KeyTable.XF86XK_MonBrightnessDown);
 | 
			
		||||
addStandard("BrightnessUp", KeyTable.XF86XK_MonBrightnessUp);
 | 
			
		||||
addStandard("Eject", KeyTable.XF86XK_Eject);
 | 
			
		||||
addStandard("LogOff", KeyTable.XF86XK_LogOff);
 | 
			
		||||
addStandard("Power", KeyTable.XF86XK_PowerOff);
 | 
			
		||||
addStandard("PowerOff", KeyTable.XF86XK_PowerDown);
 | 
			
		||||
addStandard("PrintScreen", KeyTable.XK_Print);
 | 
			
		||||
addStandard("Hibernate", KeyTable.XF86XK_Hibernate);
 | 
			
		||||
addStandard("Standby", KeyTable.XF86XK_Standby);
 | 
			
		||||
addStandard("WakeUp", KeyTable.XF86XK_WakeUp);
 | 
			
		||||
 | 
			
		||||
// 3.8. IME and Composition Keys
 | 
			
		||||
 | 
			
		||||
addStandard("AllCandidates", KeyTable.XK_MultipleCandidate);
 | 
			
		||||
addStandard("Alphanumeric", KeyTable.XK_Eisu_toggle);
 | 
			
		||||
addStandard("CodeInput", KeyTable.XK_Codeinput);
 | 
			
		||||
addStandard("Compose", KeyTable.XK_Multi_key);
 | 
			
		||||
addStandard("Convert", KeyTable.XK_Henkan);
 | 
			
		||||
// - Dead
 | 
			
		||||
// - FinalMode
 | 
			
		||||
addStandard("GroupFirst", KeyTable.XK_ISO_First_Group);
 | 
			
		||||
addStandard("GroupLast", KeyTable.XK_ISO_Last_Group);
 | 
			
		||||
addStandard("GroupNext", KeyTable.XK_ISO_Next_Group);
 | 
			
		||||
addStandard("GroupPrevious", KeyTable.XK_ISO_Prev_Group);
 | 
			
		||||
// - ModeChange (XK_Mode_switch is often used for AltGr)
 | 
			
		||||
// - NextCandidate
 | 
			
		||||
addStandard("NonConvert", KeyTable.XK_Muhenkan);
 | 
			
		||||
addStandard("PreviousCandidate", KeyTable.XK_PreviousCandidate);
 | 
			
		||||
// - Process
 | 
			
		||||
addStandard("SingleCandidate", KeyTable.XK_SingleCandidate);
 | 
			
		||||
addStandard("HangulMode", KeyTable.XK_Hangul);
 | 
			
		||||
addStandard("HanjaMode", KeyTable.XK_Hangul_Hanja);
 | 
			
		||||
addStandard("JunjaMode", KeyTable.XK_Hangul_Jeonja);
 | 
			
		||||
addStandard("Eisu", KeyTable.XK_Eisu_toggle);
 | 
			
		||||
addStandard("Hankaku", KeyTable.XK_Hankaku);
 | 
			
		||||
addStandard("Hiragana", KeyTable.XK_Hiragana);
 | 
			
		||||
addStandard("HiraganaKatakana", KeyTable.XK_Hiragana_Katakana);
 | 
			
		||||
addStandard("KanaMode", KeyTable.XK_Kana_Shift); // could also be _Kana_Lock
 | 
			
		||||
addStandard("KanjiMode", KeyTable.XK_Kanji);
 | 
			
		||||
addStandard("Katakana", KeyTable.XK_Katakana);
 | 
			
		||||
addStandard("Romaji", KeyTable.XK_Romaji);
 | 
			
		||||
addStandard("Zenkaku", KeyTable.XK_Zenkaku);
 | 
			
		||||
addStandard("ZenkakuHankaku", KeyTable.XK_Zenkaku_Hankaku);
 | 
			
		||||
 | 
			
		||||
// 3.9. General-Purpose Function Keys
 | 
			
		||||
 | 
			
		||||
addStandard("F1", KeyTable.XK_F1);
 | 
			
		||||
addStandard("F2", KeyTable.XK_F2);
 | 
			
		||||
addStandard("F3", KeyTable.XK_F3);
 | 
			
		||||
addStandard("F4", KeyTable.XK_F4);
 | 
			
		||||
addStandard("F5", KeyTable.XK_F5);
 | 
			
		||||
addStandard("F6", KeyTable.XK_F6);
 | 
			
		||||
addStandard("F7", KeyTable.XK_F7);
 | 
			
		||||
addStandard("F8", KeyTable.XK_F8);
 | 
			
		||||
addStandard("F9", KeyTable.XK_F9);
 | 
			
		||||
addStandard("F10", KeyTable.XK_F10);
 | 
			
		||||
addStandard("F11", KeyTable.XK_F11);
 | 
			
		||||
addStandard("F12", KeyTable.XK_F12);
 | 
			
		||||
addStandard("F13", KeyTable.XK_F13);
 | 
			
		||||
addStandard("F14", KeyTable.XK_F14);
 | 
			
		||||
addStandard("F15", KeyTable.XK_F15);
 | 
			
		||||
addStandard("F16", KeyTable.XK_F16);
 | 
			
		||||
addStandard("F17", KeyTable.XK_F17);
 | 
			
		||||
addStandard("F18", KeyTable.XK_F18);
 | 
			
		||||
addStandard("F19", KeyTable.XK_F19);
 | 
			
		||||
addStandard("F20", KeyTable.XK_F20);
 | 
			
		||||
addStandard("F21", KeyTable.XK_F21);
 | 
			
		||||
addStandard("F22", KeyTable.XK_F22);
 | 
			
		||||
addStandard("F23", KeyTable.XK_F23);
 | 
			
		||||
addStandard("F24", KeyTable.XK_F24);
 | 
			
		||||
addStandard("F25", KeyTable.XK_F25);
 | 
			
		||||
addStandard("F26", KeyTable.XK_F26);
 | 
			
		||||
addStandard("F27", KeyTable.XK_F27);
 | 
			
		||||
addStandard("F28", KeyTable.XK_F28);
 | 
			
		||||
addStandard("F29", KeyTable.XK_F29);
 | 
			
		||||
addStandard("F30", KeyTable.XK_F30);
 | 
			
		||||
addStandard("F31", KeyTable.XK_F31);
 | 
			
		||||
addStandard("F32", KeyTable.XK_F32);
 | 
			
		||||
addStandard("F33", KeyTable.XK_F33);
 | 
			
		||||
addStandard("F34", KeyTable.XK_F34);
 | 
			
		||||
addStandard("F35", KeyTable.XK_F35);
 | 
			
		||||
// - Soft1...
 | 
			
		||||
 | 
			
		||||
// 3.10. Multimedia Keys
 | 
			
		||||
 | 
			
		||||
// - ChannelDown
 | 
			
		||||
// - ChannelUp
 | 
			
		||||
addStandard("Close", KeyTable.XF86XK_Close);
 | 
			
		||||
addStandard("MailForward", KeyTable.XF86XK_MailForward);
 | 
			
		||||
addStandard("MailReply", KeyTable.XF86XK_Reply);
 | 
			
		||||
addStandard("MailSend", KeyTable.XF86XK_Send);
 | 
			
		||||
// - MediaClose
 | 
			
		||||
addStandard("MediaFastForward", KeyTable.XF86XK_AudioForward);
 | 
			
		||||
addStandard("MediaPause", KeyTable.XF86XK_AudioPause);
 | 
			
		||||
addStandard("MediaPlay", KeyTable.XF86XK_AudioPlay);
 | 
			
		||||
// - MediaPlayPause
 | 
			
		||||
addStandard("MediaRecord", KeyTable.XF86XK_AudioRecord);
 | 
			
		||||
addStandard("MediaRewind", KeyTable.XF86XK_AudioRewind);
 | 
			
		||||
addStandard("MediaStop", KeyTable.XF86XK_AudioStop);
 | 
			
		||||
addStandard("MediaTrackNext", KeyTable.XF86XK_AudioNext);
 | 
			
		||||
addStandard("MediaTrackPrevious", KeyTable.XF86XK_AudioPrev);
 | 
			
		||||
addStandard("New", KeyTable.XF86XK_New);
 | 
			
		||||
addStandard("Open", KeyTable.XF86XK_Open);
 | 
			
		||||
addStandard("Print", KeyTable.XK_Print);
 | 
			
		||||
addStandard("Save", KeyTable.XF86XK_Save);
 | 
			
		||||
addStandard("SpellCheck", KeyTable.XF86XK_Spell);
 | 
			
		||||
 | 
			
		||||
// 3.11. Multimedia Numpad Keys
 | 
			
		||||
 | 
			
		||||
// - Key11
 | 
			
		||||
// - Key12
 | 
			
		||||
 | 
			
		||||
// 3.12. Audio Keys
 | 
			
		||||
 | 
			
		||||
// - AudioBalanceLeft
 | 
			
		||||
// - AudioBalanceRight
 | 
			
		||||
// - AudioBassBoostDown
 | 
			
		||||
// - AudioBassBoostToggle
 | 
			
		||||
// - AudioBassBoostUp
 | 
			
		||||
// - AudioFaderFront
 | 
			
		||||
// - AudioFaderRear
 | 
			
		||||
// - AudioSurroundModeNext
 | 
			
		||||
// - AudioTrebleDown
 | 
			
		||||
// - AudioTrebleUp
 | 
			
		||||
addStandard("AudioVolumeDown", KeyTable.XF86XK_AudioLowerVolume);
 | 
			
		||||
addStandard("AudioVolumeUp", KeyTable.XF86XK_AudioRaiseVolume);
 | 
			
		||||
addStandard("AudioVolumeMute", KeyTable.XF86XK_AudioMute);
 | 
			
		||||
// - MicrophoneToggle
 | 
			
		||||
// - MicrophoneVolumeDown
 | 
			
		||||
// - MicrophoneVolumeUp
 | 
			
		||||
addStandard("MicrophoneVolumeMute", KeyTable.XF86XK_AudioMicMute);
 | 
			
		||||
 | 
			
		||||
// 3.13. Speech Keys
 | 
			
		||||
 | 
			
		||||
// - SpeechCorrectionList
 | 
			
		||||
// - SpeechInputToggle
 | 
			
		||||
 | 
			
		||||
// 3.14. Application Keys
 | 
			
		||||
 | 
			
		||||
addStandard("LaunchApplication1", KeyTable.XF86XK_MyComputer);
 | 
			
		||||
addStandard("LaunchApplication2", KeyTable.XF86XK_Calculator);
 | 
			
		||||
addStandard("LaunchCalendar", KeyTable.XF86XK_Calendar);
 | 
			
		||||
// - LaunchContacts
 | 
			
		||||
addStandard("LaunchMail", KeyTable.XF86XK_Mail);
 | 
			
		||||
addStandard("LaunchMediaPlayer", KeyTable.XF86XK_AudioMedia);
 | 
			
		||||
addStandard("LaunchMusicPlayer", KeyTable.XF86XK_Music);
 | 
			
		||||
addStandard("LaunchPhone", KeyTable.XF86XK_Phone);
 | 
			
		||||
addStandard("LaunchScreenSaver", KeyTable.XF86XK_ScreenSaver);
 | 
			
		||||
addStandard("LaunchSpreadsheet", KeyTable.XF86XK_Excel);
 | 
			
		||||
addStandard("LaunchWebBrowser", KeyTable.XF86XK_WWW);
 | 
			
		||||
addStandard("LaunchWebCam", KeyTable.XF86XK_WebCam);
 | 
			
		||||
addStandard("LaunchWordProcessor", KeyTable.XF86XK_Word);
 | 
			
		||||
 | 
			
		||||
// 3.15. Browser Keys
 | 
			
		||||
 | 
			
		||||
addStandard("BrowserBack", KeyTable.XF86XK_Back);
 | 
			
		||||
addStandard("BrowserFavorites", KeyTable.XF86XK_Favorites);
 | 
			
		||||
addStandard("BrowserForward", KeyTable.XF86XK_Forward);
 | 
			
		||||
addStandard("BrowserHome", KeyTable.XF86XK_HomePage);
 | 
			
		||||
addStandard("BrowserRefresh", KeyTable.XF86XK_Refresh);
 | 
			
		||||
addStandard("BrowserSearch", KeyTable.XF86XK_Search);
 | 
			
		||||
addStandard("BrowserStop", KeyTable.XF86XK_Stop);
 | 
			
		||||
 | 
			
		||||
// 3.16. Mobile Phone Keys
 | 
			
		||||
 | 
			
		||||
// - A whole bunch...
 | 
			
		||||
 | 
			
		||||
// 3.17. TV Keys
 | 
			
		||||
 | 
			
		||||
// - A whole bunch...
 | 
			
		||||
 | 
			
		||||
// 3.18. Media Controller Keys
 | 
			
		||||
 | 
			
		||||
// - A whole bunch...
 | 
			
		||||
addStandard("Dimmer", KeyTable.XF86XK_BrightnessAdjust);
 | 
			
		||||
addStandard("MediaAudioTrack", KeyTable.XF86XK_AudioCycleTrack);
 | 
			
		||||
addStandard("RandomToggle", KeyTable.XF86XK_AudioRandomPlay);
 | 
			
		||||
addStandard("SplitScreenToggle", KeyTable.XF86XK_SplitScreen);
 | 
			
		||||
addStandard("Subtitle", KeyTable.XF86XK_Subtitle);
 | 
			
		||||
addStandard("VideoModeNext", KeyTable.XF86XK_Next_VMode);
 | 
			
		||||
 | 
			
		||||
// Extra: Numpad
 | 
			
		||||
 | 
			
		||||
addNumpad("=", KeyTable.XK_equal, KeyTable.XK_KP_Equal);
 | 
			
		||||
addNumpad("+", KeyTable.XK_plus, KeyTable.XK_KP_Add);
 | 
			
		||||
addNumpad("-", KeyTable.XK_minus, KeyTable.XK_KP_Subtract);
 | 
			
		||||
addNumpad("*", KeyTable.XK_asterisk, KeyTable.XK_KP_Multiply);
 | 
			
		||||
addNumpad("/", KeyTable.XK_slash, KeyTable.XK_KP_Divide);
 | 
			
		||||
addNumpad(".", KeyTable.XK_period, KeyTable.XK_KP_Decimal);
 | 
			
		||||
addNumpad(",", KeyTable.XK_comma, KeyTable.XK_KP_Separator);
 | 
			
		||||
addNumpad("0", KeyTable.XK_0, KeyTable.XK_KP_0);
 | 
			
		||||
addNumpad("1", KeyTable.XK_1, KeyTable.XK_KP_1);
 | 
			
		||||
addNumpad("2", KeyTable.XK_2, KeyTable.XK_KP_2);
 | 
			
		||||
addNumpad("3", KeyTable.XK_3, KeyTable.XK_KP_3);
 | 
			
		||||
addNumpad("4", KeyTable.XK_4, KeyTable.XK_KP_4);
 | 
			
		||||
addNumpad("5", KeyTable.XK_5, KeyTable.XK_KP_5);
 | 
			
		||||
addNumpad("6", KeyTable.XK_6, KeyTable.XK_KP_6);
 | 
			
		||||
addNumpad("7", KeyTable.XK_7, KeyTable.XK_KP_7);
 | 
			
		||||
addNumpad("8", KeyTable.XK_8, KeyTable.XK_KP_8);
 | 
			
		||||
addNumpad("9", KeyTable.XK_9, KeyTable.XK_KP_9);
 | 
			
		||||
 | 
			
		||||
export default DOMKeyTable;
 | 
			
		||||
							
								
								
									
										129
									
								
								VM/novnc/core/input/fixedkeys.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,129 @@
 | 
			
		||||
/*
 | 
			
		||||
 * noVNC: HTML5 VNC client
 | 
			
		||||
 * Copyright (C) 2018 The noVNC Authors
 | 
			
		||||
 * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Fallback mapping between HTML key codes (physical keys) and
 | 
			
		||||
 * HTML key values. This only works for keys that don't vary
 | 
			
		||||
 * between layouts. We also omit those who manage fine by mapping the
 | 
			
		||||
 * Unicode representation.
 | 
			
		||||
 *
 | 
			
		||||
 * See https://www.w3.org/TR/uievents-code/ for possible codes.
 | 
			
		||||
 * See https://www.w3.org/TR/uievents-key/ for possible values.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* eslint-disable key-spacing */
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
 | 
			
		||||
// 3.1.1.1. Writing System Keys
 | 
			
		||||
 | 
			
		||||
    'Backspace':        'Backspace',
 | 
			
		||||
 | 
			
		||||
// 3.1.1.2. Functional Keys
 | 
			
		||||
 | 
			
		||||
    'AltLeft':          'Alt',
 | 
			
		||||
    'AltRight':         'Alt', // This could also be 'AltGraph'
 | 
			
		||||
    'CapsLock':         'CapsLock',
 | 
			
		||||
    'ContextMenu':      'ContextMenu',
 | 
			
		||||
    'ControlLeft':      'Control',
 | 
			
		||||
    'ControlRight':     'Control',
 | 
			
		||||
    'Enter':            'Enter',
 | 
			
		||||
    'MetaLeft':         'Meta',
 | 
			
		||||
    'MetaRight':        'Meta',
 | 
			
		||||
    'ShiftLeft':        'Shift',
 | 
			
		||||
    'ShiftRight':       'Shift',
 | 
			
		||||
    'Tab':              'Tab',
 | 
			
		||||
    // FIXME: Japanese/Korean keys
 | 
			
		||||
 | 
			
		||||
// 3.1.2. Control Pad Section
 | 
			
		||||
 | 
			
		||||
    'Delete':           'Delete',
 | 
			
		||||
    'End':              'End',
 | 
			
		||||
    'Help':             'Help',
 | 
			
		||||
    'Home':             'Home',
 | 
			
		||||
    'Insert':           'Insert',
 | 
			
		||||
    'PageDown':         'PageDown',
 | 
			
		||||
    'PageUp':           'PageUp',
 | 
			
		||||
 | 
			
		||||
// 3.1.3. Arrow Pad Section
 | 
			
		||||
 | 
			
		||||
    'ArrowDown':        'ArrowDown',
 | 
			
		||||
    'ArrowLeft':        'ArrowLeft',
 | 
			
		||||
    'ArrowRight':       'ArrowRight',
 | 
			
		||||
    'ArrowUp':          'ArrowUp',
 | 
			
		||||
 | 
			
		||||
// 3.1.4. Numpad Section
 | 
			
		||||
 | 
			
		||||
    'NumLock':          'NumLock',
 | 
			
		||||
    'NumpadBackspace':  'Backspace',
 | 
			
		||||
    'NumpadClear':      'Clear',
 | 
			
		||||
 | 
			
		||||
// 3.1.5. Function Section
 | 
			
		||||
 | 
			
		||||
    'Escape':           'Escape',
 | 
			
		||||
    'F1':               'F1',
 | 
			
		||||
    'F2':               'F2',
 | 
			
		||||
    'F3':               'F3',
 | 
			
		||||
    'F4':               'F4',
 | 
			
		||||
    'F5':               'F5',
 | 
			
		||||
    'F6':               'F6',
 | 
			
		||||
    'F7':               'F7',
 | 
			
		||||
    'F8':               'F8',
 | 
			
		||||
    'F9':               'F9',
 | 
			
		||||
    'F10':              'F10',
 | 
			
		||||
    'F11':              'F11',
 | 
			
		||||
    'F12':              'F12',
 | 
			
		||||
    'F13':              'F13',
 | 
			
		||||
    'F14':              'F14',
 | 
			
		||||
    'F15':              'F15',
 | 
			
		||||
    'F16':              'F16',
 | 
			
		||||
    'F17':              'F17',
 | 
			
		||||
    'F18':              'F18',
 | 
			
		||||
    'F19':              'F19',
 | 
			
		||||
    'F20':              'F20',
 | 
			
		||||
    'F21':              'F21',
 | 
			
		||||
    'F22':              'F22',
 | 
			
		||||
    'F23':              'F23',
 | 
			
		||||
    'F24':              'F24',
 | 
			
		||||
    'F25':              'F25',
 | 
			
		||||
    'F26':              'F26',
 | 
			
		||||
    'F27':              'F27',
 | 
			
		||||
    'F28':              'F28',
 | 
			
		||||
    'F29':              'F29',
 | 
			
		||||
    'F30':              'F30',
 | 
			
		||||
    'F31':              'F31',
 | 
			
		||||
    'F32':              'F32',
 | 
			
		||||
    'F33':              'F33',
 | 
			
		||||
    'F34':              'F34',
 | 
			
		||||
    'F35':              'F35',
 | 
			
		||||
    'PrintScreen':      'PrintScreen',
 | 
			
		||||
    'ScrollLock':       'ScrollLock',
 | 
			
		||||
    'Pause':            'Pause',
 | 
			
		||||
 | 
			
		||||
// 3.1.6. Media Keys
 | 
			
		||||
 | 
			
		||||
    'BrowserBack':      'BrowserBack',
 | 
			
		||||
    'BrowserFavorites': 'BrowserFavorites',
 | 
			
		||||
    'BrowserForward':   'BrowserForward',
 | 
			
		||||
    'BrowserHome':      'BrowserHome',
 | 
			
		||||
    'BrowserRefresh':   'BrowserRefresh',
 | 
			
		||||
    'BrowserSearch':    'BrowserSearch',
 | 
			
		||||
    'BrowserStop':      'BrowserStop',
 | 
			
		||||
    'Eject':            'Eject',
 | 
			
		||||
    'LaunchApp1':       'LaunchMyComputer',
 | 
			
		||||
    'LaunchApp2':       'LaunchCalendar',
 | 
			
		||||
    'LaunchMail':       'LaunchMail',
 | 
			
		||||
    'MediaPlayPause':   'MediaPlay',
 | 
			
		||||
    'MediaStop':        'MediaStop',
 | 
			
		||||
    'MediaTrackNext':   'MediaTrackNext',
 | 
			
		||||
    'MediaTrackPrevious': 'MediaTrackPrevious',
 | 
			
		||||
    'Power':            'Power',
 | 
			
		||||
    'Sleep':            'Sleep',
 | 
			
		||||
    'AudioVolumeDown':  'AudioVolumeDown',
 | 
			
		||||
    'AudioVolumeMute':  'AudioVolumeMute',
 | 
			
		||||
    'AudioVolumeUp':    'AudioVolumeUp',
 | 
			
		||||
    'WakeUp':           'WakeUp',
 | 
			
		||||
};
 | 
			
		||||