From afa78fcc3d7534e297a431d848373d1ab07bb754 Mon Sep 17 00:00:00 2001 From: mopsicus Date: Thu, 10 Oct 2024 16:40:27 +0300 Subject: [PATCH] feat: release --- CHANGELOG.md | 7 + CHANGELOG.md.meta | 7 + CODE_OF_CONDUCT.md | 44 + CODE_OF_CONDUCT.md.meta | 7 + CONTRIBUTING.md | 92 + CONTRIBUTING.md.meta | 7 + Documentation~/building.md | 16 + Documentation~/index.md | 53 + Documentation~/overview.md | 44 + Documentation~/reference.md | 1152 +++ Documentation~/using.md | 153 + Documentation~/welcome.md | 130 + LICENSE.md | 22 + LICENSE.md.meta | 7 + Media.meta | 8 + Media/demo-app.png | Bin 0 -> 23235 bytes Media/demo-app.png.meta | 140 + Media/logo-unity-dark.png | Bin 0 -> 18778 bytes Media/logo-unity-dark.png.meta | 133 + Media/logo-unity.png | Bin 0 -> 18778 bytes Media/logo-unity.png.meta | 133 + Media/tic-tac-toe.png | Bin 0 -> 223074 bytes Media/tic-tac-toe.png.meta | 140 + README.md | 209 + README.md.meta | 7 + README.ru.md | 209 + README.ru.md.meta | 7 + Runtime.meta | 8 + Runtime/Block.cs | 62 + Runtime/Block.cs.meta | 11 + Runtime/BlockData.cs | 34 + Runtime/BlockData.cs.meta | 11 + Runtime/BlockType.cs | 33 + Runtime/BlockType.cs.meta | 11 + Runtime/Client.cs | 234 + Runtime/Client.cs.meta | 11 + Runtime/ClientOptions.cs | 50 + Runtime/ClientOptions.cs.meta | 11 + Runtime/Commander.cs | 595 ++ Runtime/Commander.cs.meta | 11 + Runtime/Connection.cs | 364 + Runtime/Connection.cs.meta | 11 + Runtime/DisconnectReason.cs | 33 + Runtime/DisconnectReason.cs.meta | 11 + Runtime/ISerializer.cs | 23 + Runtime/ISerializer.cs.meta | 11 + Runtime/IValidator.cs | 30 + Runtime/IValidator.cs.meta | 11 + Runtime/Logger.cs | 119 + Runtime/Logger.cs.meta | 11 + Runtime/Payload.cs | 42 + Runtime/Payload.cs.meta | 11 + Runtime/PayloadData.cs | 52 + Runtime/PayloadData.cs.meta | 11 + Runtime/PayloadType.cs | 23 + Runtime/PayloadType.cs.meta | 11 + Runtime/Plugins.meta | 8 + Runtime/Plugins/WebGL.meta | 8 + Runtime/Plugins/WebGL/websocket.jslib | 317 + Runtime/Plugins/WebGL/websocket.jslib.meta | 32 + Runtime/Plugins/iOS.meta | 8 + Runtime/Plugins/iOS/IPv6.mm | 45 + Runtime/Plugins/iOS/IPv6.mm.meta | 37 + Runtime/Protocol.cs | 244 + Runtime/Protocol.cs.meta | 11 + Runtime/Pulse.cs | 62 + Runtime/Pulse.cs.meta | 11 + Runtime/ReceivedData.cs | 28 + Runtime/ReceivedData.cs.meta | 11 + Runtime/Shardy.asmdef | 14 + Runtime/Shardy.asmdef.meta | 7 + Runtime/Transport.cs | 360 + Runtime/Transport.cs.meta | 11 + Runtime/TransportType.cs | 18 + Runtime/TransportType.cs.meta | 11 + Runtime/Utils.cs | 134 + Runtime/Utils.cs.meta | 11 + Runtime/ValidatorState.cs | 18 + Runtime/ValidatorState.cs.meta | 11 + Runtime/WebSocket.cs | 291 + Runtime/WebSocket.cs.meta | 11 + Runtime/WebSocketManager.cs | 219 + Runtime/WebSocketManager.cs.meta | 11 + Samples~/Demo.meta | 8 + Samples~/Demo/Scenes.meta | 8 + Samples~/Demo/Scenes/Demo.unity | 6314 +++++++++++++++++ Samples~/Demo/Scenes/Demo.unity.meta | 7 + Samples~/Demo/Scripts.meta | 8 + Samples~/Demo/Scripts/Demo.cs | 263 + Samples~/Demo/Scripts/Demo.cs.meta | 11 + Samples~/Demo/Scripts/MyHandshake.cs | 38 + Samples~/Demo/Scripts/MyHandshake.cs.meta | 11 + Samples~/Demo/Scripts/MyJSON.cs | 30 + Samples~/Demo/Scripts/MyJSON.cs.meta | 11 + Samples~/Demo/Scripts/NiceJson.cs | 769 ++ Samples~/Demo/Scripts/NiceJson.cs.meta | 11 + Samples~/TicTacToe.meta | 8 + Samples~/TicTacToe/Images.meta | 8 + Samples~/TicTacToe/Images/circle-icon.png | Bin 0 -> 9648 bytes .../TicTacToe/Images/circle-icon.png.meta | 140 + Samples~/TicTacToe/Images/cross-icon.png | Bin 0 -> 3083 bytes Samples~/TicTacToe/Images/cross-icon.png.meta | 140 + Samples~/TicTacToe/Scenes.meta | 8 + Samples~/TicTacToe/Scenes/Game.unity | 2589 +++++++ Samples~/TicTacToe/Scenes/Game.unity.meta | 7 + Samples~/TicTacToe/Scenes/Menu.unity | 3722 ++++++++++ Samples~/TicTacToe/Scenes/Menu.unity.meta | 7 + Samples~/TicTacToe/Scripts.meta | 8 + Samples~/TicTacToe/Scripts/Connector.cs | 30 + Samples~/TicTacToe/Scripts/Connector.cs.meta | 11 + Samples~/TicTacToe/Scripts/Consts.cs | 42 + Samples~/TicTacToe/Scripts/Consts.cs.meta | 11 + Samples~/TicTacToe/Scripts/GameController.cs | 246 + .../TicTacToe/Scripts/GameController.cs.meta | 11 + Samples~/TicTacToe/Scripts/ItemButton.cs | 39 + Samples~/TicTacToe/Scripts/ItemButton.cs.meta | 11 + Samples~/TicTacToe/Scripts/MenuController.cs | 136 + .../TicTacToe/Scripts/MenuController.cs.meta | 11 + Samples~/TicTacToe/Scripts/TestHandshake.cs | 38 + .../TicTacToe/Scripts/TestHandshake.cs.meta | 11 + Samples~/TicTacToe/Scripts/TestSerializer.cs | 30 + .../TicTacToe/Scripts/TestSerializer.cs.meta | 11 + package.json | 43 + package.json.meta | 7 + 124 files changed, 21346 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 CHANGELOG.md.meta create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CODE_OF_CONDUCT.md.meta create mode 100644 CONTRIBUTING.md create mode 100644 CONTRIBUTING.md.meta create mode 100644 Documentation~/building.md create mode 100644 Documentation~/index.md create mode 100644 Documentation~/overview.md create mode 100644 Documentation~/reference.md create mode 100644 Documentation~/using.md create mode 100644 Documentation~/welcome.md create mode 100644 LICENSE.md create mode 100644 LICENSE.md.meta create mode 100644 Media.meta create mode 100644 Media/demo-app.png create mode 100644 Media/demo-app.png.meta create mode 100644 Media/logo-unity-dark.png create mode 100644 Media/logo-unity-dark.png.meta create mode 100644 Media/logo-unity.png create mode 100644 Media/logo-unity.png.meta create mode 100644 Media/tic-tac-toe.png create mode 100644 Media/tic-tac-toe.png.meta create mode 100644 README.md create mode 100644 README.md.meta create mode 100644 README.ru.md create mode 100644 README.ru.md.meta create mode 100644 Runtime.meta create mode 100644 Runtime/Block.cs create mode 100644 Runtime/Block.cs.meta create mode 100644 Runtime/BlockData.cs create mode 100644 Runtime/BlockData.cs.meta create mode 100644 Runtime/BlockType.cs create mode 100644 Runtime/BlockType.cs.meta create mode 100644 Runtime/Client.cs create mode 100644 Runtime/Client.cs.meta create mode 100644 Runtime/ClientOptions.cs create mode 100644 Runtime/ClientOptions.cs.meta create mode 100644 Runtime/Commander.cs create mode 100644 Runtime/Commander.cs.meta create mode 100644 Runtime/Connection.cs create mode 100644 Runtime/Connection.cs.meta create mode 100644 Runtime/DisconnectReason.cs create mode 100644 Runtime/DisconnectReason.cs.meta create mode 100644 Runtime/ISerializer.cs create mode 100644 Runtime/ISerializer.cs.meta create mode 100644 Runtime/IValidator.cs create mode 100644 Runtime/IValidator.cs.meta create mode 100644 Runtime/Logger.cs create mode 100644 Runtime/Logger.cs.meta create mode 100644 Runtime/Payload.cs create mode 100644 Runtime/Payload.cs.meta create mode 100644 Runtime/PayloadData.cs create mode 100644 Runtime/PayloadData.cs.meta create mode 100644 Runtime/PayloadType.cs create mode 100644 Runtime/PayloadType.cs.meta create mode 100644 Runtime/Plugins.meta create mode 100644 Runtime/Plugins/WebGL.meta create mode 100644 Runtime/Plugins/WebGL/websocket.jslib create mode 100644 Runtime/Plugins/WebGL/websocket.jslib.meta create mode 100644 Runtime/Plugins/iOS.meta create mode 100644 Runtime/Plugins/iOS/IPv6.mm create mode 100644 Runtime/Plugins/iOS/IPv6.mm.meta create mode 100644 Runtime/Protocol.cs create mode 100644 Runtime/Protocol.cs.meta create mode 100644 Runtime/Pulse.cs create mode 100644 Runtime/Pulse.cs.meta create mode 100644 Runtime/ReceivedData.cs create mode 100644 Runtime/ReceivedData.cs.meta create mode 100644 Runtime/Shardy.asmdef create mode 100644 Runtime/Shardy.asmdef.meta create mode 100644 Runtime/Transport.cs create mode 100644 Runtime/Transport.cs.meta create mode 100644 Runtime/TransportType.cs create mode 100644 Runtime/TransportType.cs.meta create mode 100644 Runtime/Utils.cs create mode 100644 Runtime/Utils.cs.meta create mode 100644 Runtime/ValidatorState.cs create mode 100644 Runtime/ValidatorState.cs.meta create mode 100644 Runtime/WebSocket.cs create mode 100644 Runtime/WebSocket.cs.meta create mode 100644 Runtime/WebSocketManager.cs create mode 100644 Runtime/WebSocketManager.cs.meta create mode 100644 Samples~/Demo.meta create mode 100644 Samples~/Demo/Scenes.meta create mode 100644 Samples~/Demo/Scenes/Demo.unity create mode 100644 Samples~/Demo/Scenes/Demo.unity.meta create mode 100644 Samples~/Demo/Scripts.meta create mode 100644 Samples~/Demo/Scripts/Demo.cs create mode 100644 Samples~/Demo/Scripts/Demo.cs.meta create mode 100644 Samples~/Demo/Scripts/MyHandshake.cs create mode 100644 Samples~/Demo/Scripts/MyHandshake.cs.meta create mode 100644 Samples~/Demo/Scripts/MyJSON.cs create mode 100644 Samples~/Demo/Scripts/MyJSON.cs.meta create mode 100644 Samples~/Demo/Scripts/NiceJson.cs create mode 100644 Samples~/Demo/Scripts/NiceJson.cs.meta create mode 100644 Samples~/TicTacToe.meta create mode 100644 Samples~/TicTacToe/Images.meta create mode 100644 Samples~/TicTacToe/Images/circle-icon.png create mode 100644 Samples~/TicTacToe/Images/circle-icon.png.meta create mode 100644 Samples~/TicTacToe/Images/cross-icon.png create mode 100644 Samples~/TicTacToe/Images/cross-icon.png.meta create mode 100644 Samples~/TicTacToe/Scenes.meta create mode 100644 Samples~/TicTacToe/Scenes/Game.unity create mode 100644 Samples~/TicTacToe/Scenes/Game.unity.meta create mode 100644 Samples~/TicTacToe/Scenes/Menu.unity create mode 100644 Samples~/TicTacToe/Scenes/Menu.unity.meta create mode 100644 Samples~/TicTacToe/Scripts.meta create mode 100644 Samples~/TicTacToe/Scripts/Connector.cs create mode 100644 Samples~/TicTacToe/Scripts/Connector.cs.meta create mode 100644 Samples~/TicTacToe/Scripts/Consts.cs create mode 100644 Samples~/TicTacToe/Scripts/Consts.cs.meta create mode 100644 Samples~/TicTacToe/Scripts/GameController.cs create mode 100644 Samples~/TicTacToe/Scripts/GameController.cs.meta create mode 100644 Samples~/TicTacToe/Scripts/ItemButton.cs create mode 100644 Samples~/TicTacToe/Scripts/ItemButton.cs.meta create mode 100644 Samples~/TicTacToe/Scripts/MenuController.cs create mode 100644 Samples~/TicTacToe/Scripts/MenuController.cs.meta create mode 100644 Samples~/TicTacToe/Scripts/TestHandshake.cs create mode 100644 Samples~/TicTacToe/Scripts/TestHandshake.cs.meta create mode 100644 Samples~/TicTacToe/Scripts/TestSerializer.cs create mode 100644 Samples~/TicTacToe/Scripts/TestSerializer.cs.meta create mode 100644 package.json create mode 100644 package.json.meta diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3b7888d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +## [1.0.0] - 2023-10-10 + +### First release of Shardy \ No newline at end of file diff --git a/CHANGELOG.md.meta b/CHANGELOG.md.meta new file mode 100644 index 0000000..e128513 --- /dev/null +++ b/CHANGELOG.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e0d7c4aaaa99b403e9b9da190915cb53 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..0469674 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,44 @@ +# Code of Conduct - Shardy + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Any insults or humiliation based on nationality or actions related to collective responsibility +* Publishing others' private information, such as a physical or email address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at mail@mopsicus.ru. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version [1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and [2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md). \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md.meta b/CODE_OF_CONDUCT.md.meta new file mode 100644 index 0000000..f842f3e --- /dev/null +++ b/CODE_OF_CONDUCT.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 53a956e1e15f449b68fa769d028c4281 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..730dbd3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,92 @@ +# Contributing to Shardy + +First off, thanks for taking the time to contribute! ❤️ + +All types of contributions are encouraged and valued. See the sections below for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉 + +> [!NOTE] +> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: +> - Star the project +> - Tweet about it +> - Refer this project in your project's readme +> - Donate in any way convenient for you +> - Mention the project at local meetups and tell your friends/colleagues + +## Code of Conduct + +This project and everyone participating in it is governed by the [Shardy Code of Conduct](./CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to mail@mopsicus.ru. + +## I have a question + +Before you ask a question, it is best to search for existing [Issues](https://github.com/mopsicus/shardy-unity/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. + +If you then still feel the need to ask a question and need clarification, we recommend the following: + +- Open an [Issue](https://github.com/mopsicus/shardy-unity/issues/new) +- Provide as much context as you can about what you're running into +- Provide project and platform versions (unity, android, ios, webgl, etc), depending on what seems relevant + +We will then take care of the issue as soon as possible. + +## Types of Contributions + +Thanks for taking the time to contribute, once again! Please check out the options for how you can start contributing. + +> [!IMPORTANT] +> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license. + +### Reporting Bugs + +A good bug report shouldn’t leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible: + +- Make sure that you are using the latest version +- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions +- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/mopsicus/shardy-unity/issues?q=label%3Abug) +- Collect information about the bug: + - Stack trace (Traceback) + - OS, Platform and Version (Windows, Linux, macOS, x86, ARM) + - Unity version + - Platform target (Android, iOS, WebGL) + - Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant + - Possibly your input and the output + - Can you reliably reproduce the issue? And can you also reproduce it with older versions? + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for Unity client for Shardy, including completely new features and minor improvements to existing functionality. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. + +- Make sure that you are using the latest version +- Perform a [search](https://github.com/mopsicus/shardy-unity/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one +- Enhancement suggestions are tracked as [GitHub issues](https://github.com/mopsicus/shardy-unity/issues) +- Create new issue +- Use a **clear and descriptive title** for the issue to identify the suggestion +- Provide a **step-by-step description of the suggested enhancement** in as many details as possible +- **Explain why this enhancement would be useful** to most Shardy users. You may also want to point out the other projects that solved it better and which could serve as inspiration + +### Implementing Features + +Look through the [GitHub issues](https://github.com/mopsicus/shardy-unity/issues) for features. Anything tagged with "enhancement" is open to whoever wants to implement it. + +Ready to contribute? Here are the simple steps for local development: + +1. [Fork](https://github.com/mopsicus/shardy-unity/fork) the client for Shardy repo on GitHub +2. Clone your fork locally: + ``` + git clone git@github.com:YOUR_USERNAME/shardy-unity.git + ``` +3. Make sure you have the minimum 2022.3.x version of Unity installed +4. Create a branch for local development: + ``` + git checkout -b shardy-bugfix-or-feature + ``` +5. Implement what you wanted. Please make sure you add comments and stick to the existing code style +6. Use `.editorconfig` file to format and check warnings +7. Make sure there are no errors or warnings after assembly +8. Please, follow the [Conventional Commits](https://www.conventionalcommits.org), when you make a commit +9. Commit your changes and push your branch to GitHub: + ``` + git add . + git commit -m "feat(transport): Add UDP protocol" + git push origin shardy-bugfix-or-feature + ``` +10. Submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) through the GitHub website diff --git a/CONTRIBUTING.md.meta b/CONTRIBUTING.md.meta new file mode 100644 index 0000000..8ff0eec --- /dev/null +++ b/CONTRIBUTING.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9d61a1654618e42d1bf1a390f04257a9 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Documentation~/building.md b/Documentation~/building.md new file mode 100644 index 0000000..eec206f --- /dev/null +++ b/Documentation~/building.md @@ -0,0 +1,16 @@ +# 👾 Android and iOS + +There are no limitations for using Shardy on Android or iOS. You can create your own app for these platforms and be sure that everything will work well. + +Shardy uses the `IPv6` plugin on iOS to convert host and connection parameters. This is [required for AppStore](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW1) review, and your app may be rejected if you skip this step. + +In either case, you can use the [`TCP`](./reference.md#-transporttype) or `WebSocket` transport type as you see fit. + +# 💻 WebGL + +Shardy can only work in WebGL builds with the [`WebSocket`](./reference.md#-websocket) transport, this is a limitation of Unity and C#. + +> [!IMPORTANT] +> You can’t use any .NET networking classes within the Web platform because JavaScript code doesn’t have direct access to internet protocol (IP) sockets to implement network connectivity. Specifically, Web doesn’t support any .NET classes within the System.Net namespace. [Read Unity docs](https://docs.unity3d.com/Manual/webgl-networking.html). + +Since the `System.Net.Sockets` namespace is not supported on this platform, you cannot use the built-in WebSockets. To solve this "snag", Shardy uses a JavaScript plugin under the hood for WebGL builds, but everything is available from C# for the developer. Just use [`TransportType.WebSocket`](./reference.md#-transporttype) for your clients and services. diff --git a/Documentation~/index.md b/Documentation~/index.md new file mode 100644 index 0000000..a0fe286 --- /dev/null +++ b/Documentation~/index.md @@ -0,0 +1,53 @@ +# 💬 What is Shardy? + +- [Overview](./overview.md#-overview) +- [For whom and why](./overview.md#-for-whom-and-why) +- [Why should I use it](./overview.md#-why-should-i-use-it) +- [Plans](./overview.md#-plans) + +# 🚀 Getting started + +- [Welcome to Shardy](./welcome.md#-welcome-to-shardy) +- [Validator](./welcome.md#-validator) +- [Serializer](./welcome.md#-serializer) +- [Run HelloWorld](./welcome.md#-run-helloworld) +- [Debug and logging](./welcome.md#-debug-and-logging) + +# 🕹️ Using + +- [Connecting to server](./using.md#-connecting-to-server) +- [Make request](./using.md#-make-request) +- [Send command](./using.md#-send-command) +- [Subscribe on command](./using.md#-subscribe-on-command) +- [Subscribe on request](./using.md#-subscribe-on-request) + +# 🏗️ Building + +- [Android and iOS](./building.md#-android-and-ios) +- [WebGL](./building.md#-webgl) + +# 📑 Reference + +- [Block](./reference.md#️-block) +- [BlockData](./reference.md#️-blockdata) +- [BlockType](./reference.md#️-blocktype) +- [Client](./reference.md#-client) +- [ClientOptions](./reference.md#-clientoptions) +- [Commander](./reference.md#-commander) +- [Connection](./reference.md#-connection) +- [DisconnectReason](./reference.md#-disconnectreason) +- [ISerializer](./reference.md#️-iserializer) +- [IValidator](./reference.md#-ivalidator) +- [Logger](./reference.md#-logger) +- [Payload](./reference.md#-payload) +- [PayloadData](./reference.md#-payloaddata) +- [PayloadType](./reference.md#-payloadtype) +- [Protocol](./reference.md#️-protocol) +- [Pulse](./reference.md#-pulse) +- [ReceivedData](./reference.md#-receiveddata) +- [Transport](./reference.md#-transport) +- [TransportType](./reference.md#-transporttype) +- [Utils](./reference.md#️-utils) +- [ValidatorState](./reference.md#️-validatorstate) +- [WebSocket](./reference.md#️-websocket) +- [WebSocketManager](./reference.md#️-websocketmanager) \ No newline at end of file diff --git a/Documentation~/overview.md b/Documentation~/overview.md new file mode 100644 index 0000000..6cf1255 --- /dev/null +++ b/Documentation~/overview.md @@ -0,0 +1,44 @@ +# 💬 Overview + +This package is a Unity client for Shardy. It provides RPC framework with simple user-friendly API: requests, commands and subscribe for communication with Shardy microservices. + +[Shardy](https://github.com/mopsicus/shardy) is a server framework for online games and applications for Node.js. It provides the basic development framework for building microservices solutions: mobile, social, web, multiplayer games, realtime applications, chats, middleware services, etc. + +The main goal of Shardy is to give simple free solution for building almost any kind of online project. 💪 + +# 🥷 For whom and why + +Shardy grew out of a few scripts for internal use, as is often the case. It was mostly used as a local game backend. It was inspired by a rather famous old project - Pomelo. The package format and general concept of the RPC framework were taken from there. New features were added - the code became more complex. In the end, it was decided to rewrite everything, add WebSocket support and share it. + +I made it alone, primarily for my own needs, after several iterations of rewriting the entire codebase 😄 I'm not claiming that Shardy will work for your project, but it's a really simple solution for adding multiplayer to your game. + +If you have minimal knowledge of Node.js and TypeScript, you can easily [launch your own service on Shardy](https://github.com/mopsicus/shardy-template) and use it as a server for your game or application. + +> [!NOTE] +> This package doesn't use any third-party libraries for its work. 😎 + +# 🚀 Why should I use it + +Start your project with Shardy and rest assured: + +- **easy to use:** work with a user-friendly API and don't worry about how it works under the hood +- **mobile platforms:** build your app for Android, iOS and WebGL from one network codebase +- **fast & lightweight:** core without any 3rd party libs, pure C# +- **full docs:** Shardy provides good docs with all necessary sections and API references, also all code is coverged by comments ✌️ + +# 🗓️ Plans + +The plans are truly grand! It is to create an ecosystem for developers who will be able to build their game backend out of existing Shardy services like bricks, and compose mobile clients from Shardy modules. + +First and foremost: +- base helpers +- binding UI +- event bus +- scene/screen manager +- localization +- sound manager +- ads manager + +All of these modules will be as separate packages. The list is endless. + +Also in the plans: writing tutorials, more examples and open source game. And don't forget to [read about server-side plans](https://github.com/mopsicus/shardy/blob/main/Documentation~/overview.md#-plans) 🌐 \ No newline at end of file diff --git a/Documentation~/reference.md b/Documentation~/reference.md new file mode 100644 index 0000000..a5a347c --- /dev/null +++ b/Documentation~/reference.md @@ -0,0 +1,1152 @@ +# 🧱 Block + +The `Block` is one of the main parts of Shardy - it encodes and decodes raw data. + +Block is composed of two parts: **header** and **body**. The header part describes type and length of the block while body contains the binary payload. + +## Structure + +*type* – block type, 1 byte +- 0x01: handshake – handshake request from client to server and handshake response +- 0x02: handshake acknowledgement – handshake acknowledgement on request +- 0x03: heartbeat – empty block for check connection heartbeat +- 0x04: data – block with some data +- 0x05: kick – disconnect signal + +*length* – length of body, 3 bytes big-endian integer + +*body* – binary payload + +All transmitted data encoded to byte array and decoded to [`BlockData`](#blockdata) in [Protocol](#️-protocol), from where it is futher passed to [Commander](#-commander). + +`Block` contains 3 static methods: + +```csharp +/// +/// Encode block for transporting +/// +/// First byte is type +/// Next - length, and data +/// +/// Block type: data, kick or heartbeat +/// Body to send +/// Encoded type + body +public static byte[] Encode(BlockType type, byte[] body); + +/// +/// Decode block data +/// +/// Buffer with data to decode +/// Result with type as BlockType and body as byte array +public static BlockData Decode(byte[] data); + +/// +/// Check received block +/// +/// Byte index for BlockType +/// Is correct block or not +public static bool Check(BlockType type); +``` + +## BlockData + +`BlockData` is the structure of a single received block of data. The `Protocol` receives the type of received block and switch [`ProtocolState`](#protocolstate) if necessary, or passes the data to the `Commander` for block processing, handshaking or disconnection. + +```csharp +/// +/// Block result after decode +/// +public struct BlockData { + + /// + /// Type of block + /// + public BlockType Type; + + /// + /// Data length + /// + public int Length; + + /// + /// Data bytes array + /// + public byte[] Body; + + /// + /// Constructor + /// + /// Block type + /// Data for block + public BlockData(BlockType type, byte[] body) { + Type = type; + Length = body.Length; + Body = body; + } +} +``` + +## BlockType + +All received blocks are typed. There are now 5 types of blocks available, as described in [structure](#structure): + +```csharp +/// +/// Block type to encode +/// +public enum BlockType { + + /// + /// Handshake process + /// + Handshake, + + /// + /// Acknowledgement for success verify + /// + HandshakeAcknowledgement, + + /// + /// Ping + /// + Heartbeat, + + /// + /// Data for command, request, response + /// + Data, + + /// + /// Kick from server, disconnect + /// + Kick +} +``` + +# 👤 Client + +`Client` is the main class for connecting and interacting with Shardy-services. When you want to send a request, command or subscribe to an event from the server, you have to use the `Client` class. + +The `Client` constructor receives 4 parameters: + +- [validator](#-ivalidator) – an instance of your handshake validation class +- [serializer](#-iserializer) – an instance of your serializer data class +- [client options](#clientoptions) (optional) – connection params such as [transport type](#-transporttype) and timeouts +- handshake data (optional) – prepared handshake data to be sent after a successful connection + +```csharp +/// +/// Client constructor +/// +/// Validator +/// Serializer +/// Client options (optional) +/// Handshake after connect (optional) +public Client(IValidator validator, ISerializer serializer, ClientOptions options = null, byte[] handshake = null); +``` + +By default `Client` uses the `TCP` transport type, but this can be changed to `WebSocket` via [`ClientOptions`](#clientoptions). + +Read how to create a `Client` and connect to the Shardy-service in the [Run HelloWorld](./welcome.md#-run-helloworld) section or [Connecting to server](./using.md#-connecting-to-server) section. + +Available methods: + +```csharp +/// +/// Connect to server +/// +/// Host to connect +/// Port to connect +public async void Connect(string host, int port); + +/// +/// Disconnect from server +/// +public void Disconnect(); + +/// +/// Send command (event) to server +/// +/// Command name +/// Payload data +public void Command(string command, byte[] data = null); + +/// +/// Send request to server and wait response +/// +/// Request name +/// Answer from server +/// Request id +public int Request(string request, Action callback); + +/// +/// Send response on request from server +/// +/// Request data +/// Data +public void Response(PayloadData request, byte[] data = null); + +/// +/// Send error on request from server +/// +/// Request data +/// Error message or code +/// Data +public void Error(PayloadData request, string error, byte[] data = null); + +/// +/// Send request to server and wait response +/// +/// Request name +/// Payload data +/// Answer from server +/// Request id +public int Request(string request, byte[] data, Action callback); + +/// +/// Cancel request manually +/// +/// Request id +public void CancelRequest(int id); + +/// +/// Handshake to verify connection +/// +/// Data for handshake +public void Handshake(byte[] body = null); + +/// +/// Subscribe on command from server +/// +/// Command name +/// Callback to action +public void On(string command, Action callback); + +/// +/// Unsubscribe from command +/// If callback is null -> clear all of them +/// +/// Command name +/// Callback to unsubscribe +public void Off(string command, Action callback = null); + +/// +/// Subscribe on request from server that wait response +/// +/// Request name +/// Callback to action +public void OnRequest(string request, Action callback); + +/// +/// Unsubscribe from request from server that wait response +/// +/// Request name +/// Callback to unsubscribe +public void OffRequest(string request); + +/// +/// Destroy all +/// +public void Destroy(); +``` + +In addition, `Client` has three callbacks to manage connection and handshake statuses: + +```csharp +/// +/// Event on connected +/// +public Action OnConnect = delegate { }; + +/// +/// Event on disconnected +/// +public Action OnDisconnect = delegate { }; + +/// +/// Event when ready to work +/// +public Action OnReady = delegate { }; +``` + +There is also a property to check the current state of the connection: + +```csharp +/// +/// Is client connected +/// +public bool IsConnected; +``` + +## ClientOptions + +`ClientOptions` is used to pass pre-configured connection parameters to `Client`: + +- transport type – type of connection transport: tcp or websocket +- buffer size – lenght of loaded data +- request timeout – timeout (ms) for RPC requests +- pulse interval – interval (ms) for checking connection heartbeat + +```csharp +/// +/// Client and connection options +/// +public class ClientOptions { + + /// + /// Transport type: TCP or WebSocket + /// + public TransportType Type = TransportType.Tcp; + + /// + /// Transport buffer size + /// + public int BufferSize = 1024; + + /// + /// Timeout for RPC request (ms) + /// + public float RequestTimeout = 10000f; + + /// + /// Interval for checking server (ms) + /// + public float PulseInterval = 1000f; + + /// + /// Options constructor + /// + /// Transport type + public ClientOptions(TransportType type = TransportType.Tcp) { + Type = type; + } + + /// + /// Options constructor + /// + /// Transport type + /// Transport buffer size, Kb + /// Timeout for RPC request, ms + /// Interval for checking server, ms + public ClientOptions(TransportType type, int buffer, float timeout, float pulse) { + Type = type; + BufferSize = buffer; + RequestTimeout = timeout; + PulseInterval = pulse; + } +} +``` + +# 🔩 Commander + +The `Commander` is the next important part of Shardy – it controls how to receive and send blocks, what command or request to invoke, and when to disconnect a client or send a heartbeat. + +This is a private class for [`Client`](#-client) and all methods are not called directly, only from the `Client` instance. + +```csharp +/// +/// Start use +/// +public void Start(); + +/// +/// Add callback for request +/// +/// Request id +/// Request command +/// Request's params +/// Callback for request +void AddRequest(int id, string command, byte[] param, Action callback); + +/// +/// Remove request from list +/// +/// Request id +public void CancelRequest(int id); + +/// +/// Subscribe callback on command +/// +/// Command name +/// Callback for command +public void AddCommand(string command, Action callback); + +/// +/// Unsubscribe callback from command +/// If callback is null -> clear all of them +/// +/// Command name +/// Callback for command +public void CancelCommand(string command, Action callback); + +/// +/// Subscribe to request from server that wait response +/// +/// Request name +/// Callback on RPC +public void AddOnRequest(string request, Action callback); + +/// +/// Unsubscribe from request from server that wait response +/// +/// Request name +public void CancelOnRequest(string request); + +/// +/// Exec callback for RPC from server +/// +/// Request data +public void InvokeOnRequest(PayloadData payload); + +/// +/// Send handshake +/// +/// Data to handshake +public void Handshake(byte[] data); + +/// +/// Send acknowledge +/// +/// Data to acknowledge +public void Acknowledge(byte[] data); + +/// +/// Disconnect from server +/// +public void Disconnect(); + +/// +/// Send command (event) to server with params +/// +/// Command name +/// Payload data +public void Command(string command, byte[] data); + +/// +/// Send request to server and wait response +/// +/// Request name +/// Payload data +/// Answer from server +/// Request id +public int Request(string request, byte[] data, Action callback); + +/// +/// Send response on request from server +/// +/// Request data +/// Data +public void Response(PayloadData request, byte[] data = null); + +/// +/// Send error on request from server +/// +/// Request data +/// Error message or code +/// Data +public void Error(PayloadData request, string error, byte[] data = null); + +/// +/// Clear all events +/// +public void Clear(); + +/// +/// Destroy all +/// +public void Destroy(); +``` + +# 🌐 Connection + +`Сonnection` determines how to read and write to the socket depending on which [`TransportType`](#transporttype) is selected. + +`Сonnection` is a private class used in [`Transport`](#-transport) to receive and send data. It also detects connection loss and converts IP to IPv6 on iOS clients. + +## DisconnectReason + +In normal cases, when a client disconnects, `Client` returns the disconnect code `Normal`. If disconnection occurs at the handshake stage, the `Handshake` code will be returned. + +```csharp +/// +/// Disconnect reasons +/// +public enum DisconnectReason { + + /// + /// Normal disconnect + /// + Normal, + + /// + /// Have no answer on ping command + /// + Timeout, + + /// + /// Handshake validation failed + /// + Handshake, + + /// + /// Server is closed` + /// + ServerDown, + + /// + /// Some error occurs + /// + Unknown +} +``` + +# 🏗️ ISerializer + +Shardy supports custom serialization of transmitted data. You can use JSON, MessagePack, Protobuf, FlatBuffers, etc. or your own serializer. `ISerializer` is just an interface for your own serializer implementation. + +The main goal of this class is to encode [`PayloadData`](#payloaddata) to byte array and decode it back. + +```csharp +/// +/// Serializer interface, uses in Payload +/// +public interface ISerializer { + + /// + /// Serialize data to byte array + /// + /// Target data + /// Encoded data + byte[] Encode(PayloadData body); + + /// + /// Deserialize data + /// + /// Encoded data + /// Data to use + PayloadData Decode(byte[] body); + +} +``` + +# 🪪 IValidator + +Shardy provides an interface for handshake validation. You can implement your own handshake data structure and validation for all stages. + +Encode and validate any client-side or server-side data in the handshake process to control connected users and allow or deny them to invoke commands. + +> [!IMPORTANT] +> If your implementation does not need to do a two-step handshake, you can set "stubs" on these methods. + +When a client connects to the server, it must successfully complete the handshake before it can begin. Shardy uses a two-step handshake for connections. + +Stages of handshake: + +1. The client sends a handshake to the server +2. Server receives and verifies it: + - Sends an acknowledgement to the client + - Disconnects the client, if the verification fails +3. The client receives the acknowledgement and verifies it: + - Sends a reply acknowledgement to the server + - Disconnects, if the verification fails +4. After verifying the handshake and acknowledgement, the client and server can communicate with each other + +```csharp +/// +/// Handshake interface for client-server validation +/// +public interface IValidator { + + /// + /// Validate acknowledgement data + /// + /// Data for validate + /// Validation result + ValidatorState VerifyAcknowledgement(byte[] body); + + /// + /// Get handshake data for send + /// + /// Data for handshake + /// Data for handshake + byte[] Handshake(byte[] body = null); + + /// + /// Get acknowledgement data for send + /// + /// Data from handshake + /// Data for acknowledge + byte[] Acknowledgement(byte[] body); + +} +``` + +## ValidatorState + +Each verify method must return a typed `ValidatorState` response after processing. + +```csharp +/// +/// Validator state +/// +public enum ValidatorState { + + /// + /// Handshake passed + /// + Success, + + /// + /// Handshake failed + /// + Failed +} +``` + +# 📝 Logger + +Shardy provides a simple built-in logger. This is a wrapper for the `Console.WriteLine` and `UnityEngine.Debug.Log` methods with a few useful additions. + +```csharp +/// +/// Log info +/// +/// Data to log +/// Log label +/// Log color +public static void Info(object data, string label = "", LogColor color = LogColor.Default); + +/// +/// Log warning +/// +/// Data to log +/// Log label +/// Log color +public static void Warning(object data, string label = "", LogColor color = LogColor.Yellow); + +/// +/// Log error +/// +/// Data to log +/// Log label +/// Log color +public static void Error(object data, string label = "", LogColor color = LogColor.Red); +``` + +`LogColor` is an enum associated with preset colors. These colors are chosen for better visualization in the Unity console. + +```csharp +/// +/// Get HEX color for log +/// +/// Color index +static string GetColor(LogColor color) { + return color switch { + LogColor.Red => "#EE4B2B", + LogColor.Orange => "#FFAC1C", + LogColor.Yellow => "#FFFF8F", + LogColor.Green => "#50C878", + LogColor.Blue => "#89CFF0", + LogColor.Purple => "#BF40BF", + _ => "#CCCCCC", + }; +} +``` + +# ℹ️ Payload + +`Payload` is a static class that handles the encoding and decoding of raw data to and from [`PayloadData`](#payloaddata). It is a private class for [`Commander`](#-commander), which encodes data before sending it and decodes it after receiving it. + +```csharp +/// +/// Encode data for transfer +/// +/// Service serializer +/// Type of data +/// Request name +/// Request id +/// Data +/// Data +/// Encoded data +public static byte[] Encode(ISerializer serializer, PayloadType type, string name, int id, byte[] data, string error); + +/// +/// Decode received block +/// +/// Service serializer +/// Encoded data +/// Payload data to use in commander +public static PayloadData Decode(ISerializer serializer, byte[] data); + +/// +/// Check payload for available type +/// +/// Payload data to check +public static bool Check(PayloadData payload); +``` + +The `check` method controls that the received data is correct and available for processing. + +## PayloadData + +When [`Client`](#-client) receives data, `PayloadData` is the last structure of the entire data processing chain. `PayloadData` is the data containing the command/request meta-info and the received data, if it exists. The [`PayloadType`](#payloadtype) type in `PayloadData` determines how the data will be processed. + +```csharp +public struct PayloadData { + + /// + /// Type of data + /// + public PayloadType Type; + + /// + /// Command or request name + /// + public string Name; + + /// + /// Request id + /// + public int Id; + + /// + /// Data + /// + public byte[] Data; + + /// + /// Error message or code + /// + public string Error; + + /// + /// Constructor + /// + /// Payload type + /// Command or request name + /// Request id + /// Data + /// Error message or code + public PayloadData(PayloadType type, string name, int id, byte[] data, string error) { + Type = type; + Id = id; + Name = name; + Data = data; + Error = error; + } +} +``` + +## PayloadType + +The `PayloadType` defines how the data will be processed. + +```csharp +/// +/// Payload type command +/// +public enum PayloadType { + + /// + /// Request and expect answer + /// + Request, + + /// + /// Command without answer, event + /// + Command, + + /// + /// Response on request + /// + Response +} +``` + +# ⛓️ Protocol + +`Protocol` is an another internal class that links [`Commander`](#-commander) with [`Transport`](#-transport) and determines state of app: start, handshake or work. Each received [`Block`](#-block) from [`Transport`](#-transport) is detected, decoded to `BlockData` and passed to the `Commander` depending on the current [`Protocol State`](#-protocolstate). + +`Commander` can invoke these public methods: + +```csharp +/// +/// Start protocol and transport +/// +public void Start() { + +/// +/// Send data to connection +/// +/// Serialized command data +public void Send(byte[] body); + +/// +/// Send heartbeat to connection +/// +public void Heartbeat(); + +/// +/// Send handshake to connection +/// +/// Handshake data +public void Handshake(byte[] body); + +/// +/// Send acknowledgement +/// +/// Acknowledge data +public void Acknowledge(byte[] body); + +/// +/// Disconnect from server +/// +public void Disconnect(); + +/// +/// Destroy all +/// +public void Destroy(); +``` + +## ProtocolState + +The `Commander` can only accept requests and commands if the client has passed the handshake and the protocol state is set to `Work`. + +```csharp +/// +/// Protocol state +/// +enum ProtocolState { + + /// + /// Init state, wait for handshake + /// + Start, + + /// + /// Handshake is in progress + /// + Handshake, + + /// + /// Work state after success handshake + /// + Work, + + /// + /// Protocol closed, any actions ignored + /// + Closed +} +``` + +# 💓 Pulse + +`Pulse` is an internal class for handling the heartbeat of a connection. It uses param `PulseInterval` from the [`ClientOptions`](#clientoptions). + +When Shardy receives any command, handshake or heartbeat, the `checks` counter in `Pulse` is reset. Every `PulseInterval` this class checks the `checks` counter and if the counter value is greater than one, it invokes a callback to send a heartbeat. + +```csharp +/// +/// Reset timer when commands received +/// +public void Reset(); + +/// +/// Stop and switch off service +/// +public void Clear(); +``` + +The `Clear` method is used to stop the timer when the connection is destroyed. + +## ReceivedData + +`ReceivedData` is a temporary structure for received data. It is used in [`Connection`](#-connection) and [`Transport`](#-transport) to control the length of the received data. + +```csharp +/// +/// Data received from socket +/// +public struct ReceivedData { + + /// + /// Data length + /// + public int Length; + + /// + /// Data bytes array + /// + public byte[] Body; + +} +``` + +# 🚄 Transport + +`Transport` is one of the main parts of Shardy – it controls how data will be sent and received. + +`Transport` receives data from [`Connection`](#-connection), determines the size of the [`Block`](#-block), checks its type, and starts receiving its entire length. Once received, it passes the data to [`Protocol`](#️-protocol). + +The [`Protocol`](#️-protocol) can use these public methods or `Transport`: the `start` method is used to set initial state and begin receiveing data, the `dispatch` method is used to send data, the `close` method is used to terminate transmission, and the `destroy` method is used when the connection is destroyed. + +```csharp +/// +/// Start receiving data +/// +public void Start(); + +/// +/// Send data to socket +/// +/// Bytes array +public async void Dispatch(byte[] buffer); + +/// +/// Close this transport +/// +public void Close(); + +/// +/// Destroy all +/// +public void Destroy(); +``` + +Under the hood, the `Transport` monitors its `TransportState` and reads the right part of the data or stops the transmission. + +```csharp +/// +/// Transporter state +/// +enum TransportState { + + /// + /// Receive head data + /// + Head, + + /// + /// Receive body data + /// + Body, + + /// + /// Transport is closed, no more data received + /// + Closed +} +``` + +## TransportType + +Shardy can work with `TCP` sockets or `WebSockets`. When you configure your client, pass the desired transport type via [`ClientOptions`](#clientoptions). + +```csharp +/// +/// Type of transport +/// +public enum TransportType { + + /// + /// TCP sockets transport + /// + Tcp, + + /// + /// Websockets transport + /// + WebSocket +} +``` + +# 🛠️ Utils + +`Utils` is a small static class with a few useful functions. + +```csharp +/// +/// Custom timer for WebGL compatibility +/// +/// Interval for timer, ms +/// Cancellation source +/// Callback on tick +public static async Task SetTimer(float interval, CancellationTokenSource cancellation, Action callback); + +/// +/// Make delay +/// Hack to prevent using Task.Delay in WebGL +/// +/// Delay in ms +public static async Task SetDelay(float delay); + +/// +/// Extension to add cancellation for task +/// +public static async Task WithCancellation(this Task task, CancellationToken cancellationToken); + +/// +/// Extension to add cancellation for task +/// +public static async Task WithCancellation(this Task task, CancellationToken cancellationToken); + +/// +/// Convert data to string +/// +public static string DataToString(byte[] data); + +/// +/// Convert data to log string +/// +public static string DataToDebug(byte[] data); + +/// +/// Escape string for log +/// +/// Input string +static string ToLiteral(string data); +``` + +# 🔌 WebSocket + +`WebSocket` class is used only for [WebGL](./building.md#-webgl) builds. This is a wrapper for JS plugin and used in [`WebSocketManager`](#️-websocketmanager) as an unit for websocket connections. + +> [!NOTE] +> When you create an app with the WebSocket transport type on Android or iOS, a native implementation of WebSocket is used. + +Available methods: + +```csharp +/// +/// Create websocket +/// +public WebSocket(); + +/// +/// Create websocket +/// +/// Optional subprotocol +public WebSocket(string subprotocol); + +/// +/// Create websocket +/// +/// Optional subprotocols list +public WebSocket(List subprotocols); + +/// +/// Current state +/// +public WebSocketStateCode State; + +/// +/// Connect to server +/// +public async Task Connect(string url); + +/// +/// Close connection +/// +/// Close code +/// Reason +public bool Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null) +; +/// +/// Send data as buffer +/// +/// Array of bytes +public async Task Send(byte[] data); + +/// +/// Receive data from socket +/// +/// Buffer to write +/// Received length +public async Task Receive(byte[] buffer); +``` + +It also uses the standard WebSocket status and error codes: + +```csharp +/// +/// Websocket state codes +/// +enum WebSocketStateCode { + Connecting, + Open, + Closing, + Closed, + Error +} + +/// +/// Return error codes +/// +enum WebSocketErrorCode { + NotFound = -1, + AlreadyConnected = -2, + NotConnected = -3, + AlreadyClosing = -4, + AlreadyClosed = -5, + NotOpened = -6, + CloseFail = -7, + SendFail = -8, + Unknown = -999 +} + +/// +/// Websocket code for close +/// +enum WebSocketCloseCode { + NotSet = 0, + Normal = 1000, + Away = 1001, + ProtocolError = 1002, + UnsupportedData = 1003, + Undefined = 1004, + NoStatus = 1005, + Abnormal = 1006, + InvalidData = 1007, + PolicyViolation = 1008, + TooBig = 1009, + MandatoryExtension = 1010, + ServerError = 1011, + TlsHandshakeFailure = 1015 +} +``` + +# 🎛️ WebSocketManager + +`WebSocketManager` is a static private class for managing all [`WebSocket`](#-websocket) connections, only for WebGL builds. + +`WebSocketManager` creates websockets in the JS plugin, sets identifiers and callbacks from the plugin to the C# wrapper. + +```csharp +/// +/// Set debug mode +/// +public static void SetDebug(bool value); + +/// +/// Set callbacks +/// +public static void Init(); + +/// +/// Add new socket +/// +/// Websocket instance +/// Id +public static int Add(WebSocket socket); + +/// +/// Remove websocket instance +/// +/// Instance id +public static void Destroy(int id); +``` + +`SetDebug` takes the value `true` if the `SHARDY_DEBUG_RAW` condition is enabled. \ No newline at end of file diff --git a/Documentation~/using.md b/Documentation~/using.md new file mode 100644 index 0000000..5d19be7 --- /dev/null +++ b/Documentation~/using.md @@ -0,0 +1,153 @@ +# 🌐 Connecting to server + +To connect to the Shardy-service you have to use [`Client`](./reference.md#-client) class. Client's contructor receives some params: + +- [validator](./reference.md#-ivalidator) – custom validation class for handshake stages +- [serializer](./reference.md#-iserializer) – custom serializer of all transmitted data +- [options](./reference.md#clientoptions) (optional) – connection parameters, such as transport type and timeouts +- handshake (optional) – handshake data could be passed as last param + +> [!IMPORTANT] +> Make sure the serializer and handshake validator are the same as the service you are connecting to. + +When `Client` is created, add callbacks for events and call `connect` to connect to the server. + +```csharp +_client = new Client(new MyHandshake(), new MySerializer()); +_client.OnConnect += OnConnect; +_client.OnDisconnect += OnDisconnect; +_client.OnReady += OnReady; + +void OnConnect(bool status) { +// connect event +// status is a flag indicating whether the connection is successful or not + +// here you can send the handshake data if it was not passed through constructor +// +// if handshake data passed through constructor you shouldn't invoke Handshake() method manually + if (status) { + var data = Encoding.UTF8.GetBytes("handshake_data"); + _client.Handshake(data); + } +} + +void OnDisconnect(DisconnectReason reason) { +// disconnect event with reason +} + +void OnReady() { +// ready event, client has successfully completed the handshake +// +// ready for receive and send data +} + +_client.Connect("127.0.0.1", 30000); +``` + +# ⛓️ Make request + +> [!NOTE] +> The general difference between requests and commands that is other side must respond to requests and doesn't respond to commands. So this means that when you make a request, you have a callback with response data. And when you send a command, you are simply notifying the other side about something. + +To make a request - just use the `Request` method of the [`Client`](./reference.md#-client) and pass the name of the request: + +```csharp +_client.Request("test", (response) => { + Console.WriteLine($"received test data: ${response.ToString()}"); +}); +``` + +The second parameter is a callback with response data. You can use it as a lambda expression, as in the snippet above, or make an external method for it: + +```csharp +_client.Request("test", OnTest); + +void OnTest(PayloadData data) { + Console.WriteLine($"received test data: ${response.ToString()}"); +} +``` + +If the service does not respond or the request takes too long to complete, you will get an error in [`PayloadData`](./reference.md#payloaddata). The `Error` property is usually empty, but if an error occurred, it contains an error code or message. + +And of course you can make requests with param: + +```csharp +var data = Encoding.UTF8.GetBytes("some_data"); +_client.Request("test", data, (response) => { + if (!string.IsNullOrEmpty(response.Error)) { + // handle error here + return; + } + Console.WriteLine($"received test data: ${response.ToString()}"); +}); +``` + +Shardy accept byte array as param, so you can pass any data to request. Make sure you can deserialize and read this data on the server side 🙄 + +# 💨 Send command + +To send a command - use the `Command` method of the `Client` and pass the name of the command: + +```csharp +_client.Command("start"); +``` + +Sending command with param: + +```csharp +var data = Encoding.UTF8.GetBytes("some_data"); +_client.Command("start", data); +``` + +The command has no callback, you just send an event/notification and don't wait for a response. + +# 📭 Subscribe on command + +You can subscribe to a command from the server and process it each time it arrives. This is a popular method of updating data. + +```csharp +_client.On("lookup", (data) => { + Console.WriteLine($"received lookup data: ${data.ToString()}"); +}); +``` + +Also you can make an external method for it: + +```csharp +_client.On("lookup", OnLookup); + +void OnLookup(PayloadData data) { + Console.WriteLine($"received lookup data: ${data.ToString()}"); +} +``` + +And you can unsubscribe from it and no longer process these events: + +```csharp +_client.Off("lookup", OnLookup); +``` + +# 📮 Subscribe on request + +In rare cases you can make a request from the server to the client, this is also possible. When the server makes a request, it waits for a response, so the client must respond when it receives it, otherwise the server will timeout. + +To subscribe to a request, use the `OnRequest` method: + +```csharp +_client.OnRequest("status", (data) => { + Console.WriteLine($"received request data: ${data.ToString()}"); + // if comment lines below, you will give timeout on your backend + _client.Response(data, Encoding.UTF8.GetBytes("some_data_from_client")); + // or you can send error on received request + _client.Error(data, "error_code"); +}); +``` + +> [!IMPORTANT] +> When you make a response or send an error to a received request from the server, you must pass the received payload data as the first parameter because it contains the necessary data from the request. + +And you can also unsubscribe from it: + +```csharp +_client.OffRequest("status", OnRequestCallback); +``` \ No newline at end of file diff --git a/Documentation~/welcome.md b/Documentation~/welcome.md new file mode 100644 index 0000000..0ba595c --- /dev/null +++ b/Documentation~/welcome.md @@ -0,0 +1,130 @@ +# 🙌 Welcome to Shardy + +Shardy is a simple backend framework for Node.js written on TypeScript. + +This package is a Unity client for Shardy. It provides an RPC framework with a simple user-friendly API: requests, commands and subscribe for communication with Shardy microservices. It uses its own transport package structure, handshake stages, and custom serializer. You can't use it without [Shardy backend](https://github.com/mopsicus/shardy) because all the features are designed to work in tandem. + +# 🪪 Validator + +Shardy provides a flexible handshake procedure: + +1. The client sends a handshake to the server +2. Server receives and verifies it: + - Sends an acknowledgement to the client + - Disconnects the client, if the verification fails +3. The client receives the acknowledgement and verifies it: + - Sends a reply acknowledgement to the server + - Disconnects, if the verification fails +4. After verifying the handshake and acknowledgement, the client and server can communicate with each other + +```csharp +using Shardy; + +class MyHandshake : IValidator { + + public ValidatorState VerifyAcknowledgement(byte[] body) { + // vefify acknowledgement data + } + + public byte[] Handshake(byte[] body = null) { + // data for initial handshake + } + + public byte[] Acknowledgement(byte[] body) { + // data for acknowledgement after handshake validation passed + } +} +``` + +If your implementation does not need to do a two-step handshake, you can set "stubs" on these methods. [See demo](../Samples/Demo/) for that. The last step of the handshake procedure invokes `VerifyAcknowledgement` and returns [`ValidatorState`](./reference.md#validatorstate): success or failure, there you can set the stub if needed. + +Your handshake [validator](./reference.md#-ivalidator) class is passed to the [`Client`](./reference.md#-client) constructor as the first parameter, the next is the serializer. + +# 🧱 Serializer + +Shardy uses a custom serializer for all transmitted data. You can use JSON, MessagePack, Protobuf, FlatBuffers, etc. or your own serializer. You have to create your own serializer class by inheriting the [`Serializer`](./reference.md#-iserializer) class, implement encode/decode methods and pass it to your service and client. The main goal – encode [`PayloadData`](./reference.md#payloaddata) to byte array before sending and back after receiving. + +```csharp +using Shardy; + +class MyJsonSerializer : ISerializer { + + public byte[] Encode(PayloadData body) { + // encode PayloadData to Buffer for transporting + } + + public PayloadData Decode(byte[] body) { + // decode recevied data and serialize to PayloadData + } +} +``` + +I have plans to do some tutorials on the most popular serializers for Unity and their use with Shardy. Stay tuned. + +> [!IMPORTANT] +> Make sure your serialization and validation are the same on the server and client + +# ✨ Run HelloWorld + +Let's create a simple project. Do it in your favorite version of Unity, but don't use a version less than 2020.3.x :) + +1. Create project +2. Install Shardy + + Get it from [releases page](https://github.com/mopsicus/shardy-unity/releases) or add the line to `Packages/manifest.json` and module will be installed directly from Git url: + + ``` + "com.mopsicus.shardy": "https://github.com/mopsicus/shardy-unity.git", + ``` + +3. Implement your validator and serializer classes +4. Create `Client` and connect to server + ```csharp + void Awake() { + _client = new Client(new MyValidator(), new MySerializer()); + ... + } + + void Connect() { + _client.Connect("127.0.0.1", 30000); + } + ``` + +5. Make a request or send command + ```csharp + void TestRequest() { + _client.Request("test", (response) => { + Console.WriteLine($"received test data: ${response.ToString()}"); + }); + } + ``` + +> [!NOTE] +> This is a simple example, of course, without a backend you cannot connect and send a command + +Read how to run the [test backend](https://github.com/mopsicus/shardy/blob/main/docs/service.md#-using-template) on Shardy and explore how to [make requests and handle errors](./using.md#️-make-request) in the Unity client. + +# 📝 Debug and logging + +Shardy uses its own static class [`Logger`](./reference.md#-logger) with several addons: + +1. Labeling +2. Time formatting +3. Coloring + +```csharp +public static void Info(object data, string label = "", LogColor color = LogColor.Default); +``` + +You can set a label/tag for your message to group them, and set a custom color if desired. Shardy logger contains the common methods: *info*, *warning* and *error*. + +The time format is pre-configured and is similar to a timestamp with a time zone: + +```csharp +/// +/// Date/time format for log +/// +const string DATE_FORMAT = "yyyy-MM-ddTHH:mm:ss.msZ"; +``` + +All debug outputs are wrapped with preprocessor directives and can be enabled or disabled. Add `SHARDY_DEBUG` to show all log messages without errors and stacktraces. For more detailed logs, add `SHARDY_DEBUG_RAW` to the project scripting define symbols. \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..efde165 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2024 Mopsicus + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/LICENSE.md.meta b/LICENSE.md.meta new file mode 100644 index 0000000..2e9dbf9 --- /dev/null +++ b/LICENSE.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c761f20b47f5c464cb48979d9ec0ee71 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Media.meta b/Media.meta new file mode 100644 index 0000000..0a65ed9 --- /dev/null +++ b/Media.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fb2be8439745a43cc961a5b591409bd7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Media/demo-app.png b/Media/demo-app.png new file mode 100644 index 0000000000000000000000000000000000000000..83a02392b59f7931cdc4b3f7e25abfc1dccfee9c GIT binary patch literal 23235 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 z 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 literal 0 HcmV?d00001 diff --git a/Media/demo-app.png.meta b/Media/demo-app.png.meta new file mode 100644 index 0000000..6a74e07 --- /dev/null +++ b/Media/demo-app.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: 732010a06c6444e69a13614d173e17b7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Media/logo-unity-dark.png b/Media/logo-unity-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..b22129c2021f97440f5a812b92765e9c6559494b GIT binary patch literal 18778 zcmeFYWpL$8&^30=_BAszGp+44Gcz--?KLwq+iS)(Gcz+YGcz;OnjwDPB$ZSuzw$Sq zszxJedNk_pkxHjePnd$7I6M#s2mk=!B_%|Z007YMLr?%T*mu=mL^kqWfjBCO3xTYT z()oU$z}QJ>IsyQ&sQ(oZKw1VC000J1kWmr+Zv6UR+yAn_|6eTt#S07l{jva@l;o5F zAP~^t)Iv&TZh;B8)tS7aPKjOP^IJz3caLxXMy)7A26sQd+HtWJW?sVx-J7pJ-hadK zgq|^xr0>5hL#gK9va$9&Ln3N4q-+D#JGkxkrdbwY1b!AGb(bS&oGuKnINYq(dx`VY z;4^dzR_b955M2h*!*c2v`==h9m?PjxJvFL<&b9>qFv5w&pd}j-gZHeVT1tDM(>?~f z7a_LIL!BCuh%3pFM)?zc7#?q7g6St*wx(IsC;!)G!}pv^8GVy|X(D@)g5%0C zMkc_epw7~xs)F5AQh$dr%ixzI+MKT9m|QJ$q^z@+wNI}-Uw=fBH$gGEifdakc)wN` z03dQKDI%!imT{TsYJfKQ)N?IylBqCP;@W^Z5)Z>rB6@(;I4GIb(A|S+!1YRiS z4}j4v`~yuR5f%PGLlq8OL3*cl5qP0_ZI`aPnDS&@zhW5O^!g0AnAl2BZEjcAn?3!B zhY;GoYxn=GvPJZ%h=>%jmzC@~289F%hk~n@>Xce21X~;e4;zi~GiFEBhOJTxXXn z)yukI2tRaW{t=d{C(8r95+UJnMN>5UZAn@36!#(B>8Xc5MA*#NWGrs*e^{>Z&{Q8D zwj^WFYm1KK`{pyh&L+{{Y5j`E4Kv@QNMgC~XC7!W$4yvPa@-J6X@A5Z&(D^&dUL_Q z({hOBK6zf*56|*B*50`#!N1pXiFN_yVvA5={ak_&)G7AsNXp8Oo6>D7!~M`{b2-mg zrr$Bk^F;g`)BQm{Q}3zQ?3W*`*GcZ`vl8_0>hH4kP6uxaV?tu;)7;*T?gbn6*_V}|SXYHS3r~E_#oMnc!yxgyzK`^6*iR1d;}W{rj-W!>^dO5)@ZOiu+WbKN&_ zqJTg(r!xV#4$H-z)K_YG)hRjws;YyhGu z@}%U7B8_j9m9vT#Jv`2odlM}ZitSP30tTGM@_F7<`!2$RP2q+ui)5an5Aa-(R?t7v z#HTXYw9C#iG+AfcLaH|Gb9Qd5XxKw$9ghnomu1sA2simH?uW$)g$`5B>*&c-FR9Ua*(Uxwy6O zgeu^CJ(v2{<9Z&tRn*SNwkaS#?RI3x1PvW+rkcT;8HnCvcG4;K?!%Y{a&3rpz3F1N zFl$eb*M6g#I(7caNnd~A>q6rOxMe&vk04zC+b1# zpnHBs^&qgP@cs(hkMcg{Z7J(Y#-Pf+?uV@-9TXd1h^=B0eW(M^IhP)zoZm(c)z-eU zEy5`*#83JBh2?gW>h+cTCd`l?sPcLYMznDW#S?M?+gCoV$>CRM@762l>-eg3ZEz?$ zOqUKF$8Y|)qTR&qNj;-RMLfU|dNXL?I*!oSk@O5U0WN*e90m zy~88BL==(eRQoTyw?dFS{?Ln>>+?cH$$`w2j1300_ z8rM6__#gguG@>J-7R?VH3k-3F(B2e$dmWN*XI8XS-T-zGca#8|$O`**SwF%_(|fF# zeoqPOw1cLA*9R%=rV+0R& z85{gO;wKzGH-+Yir|!z}2ZlXbZL|%l8L7df)H!V*)B7(!1(1i!qqRpw1}~~`=&)7r zs(TmDpFl$mh;t`%QHnKhzyvxY1Q+^FU?swSx7r~@ZBC1-onX)|X3o4dk{2NzCByM& z{+T#~sbGGtOWVEL24fCU-yPhXsI>r3XmARjOBSBpbPgzRo!*2Z>T)`K4`>YonnY z#2xX6T+Zyz3T_VI^iu_+BN#6C`A>B+;ZIj9981;69L8Q=3e^HSG?K2@4erXF67sG? zh&39-A>fki8TSd!##-(GaLOGja!0NAC3RK5xfniE(Xzpgd$_CjKFaP61YfESHP~_# zbEn77&<$j+_%iZaV~H5C`;wrH@TM|feVWtKevc>?Xl1& z!gen%UD2x$0JFv28Owi|MH?bhLTza5Is~;^r6Ox3KYXN$sRml6U3=O3AXLC=zpK?H7kv#CYc0fKpCB zAAKBTprQmlSTfY0F)TEZ3vbJe`#ky}K4Y1KoYsRKh#AbO`zF*r$MDE_+QUrz3R?cOLYHQHwqP7`q@(Jbjm_5oye%xU}e}H z!>LxH(+Ctqr&X1ML4bj04Gxv5axgkPP2m32Am}gqM}E|F*n{VaS^kb{NrKp72iq!o zbmAH5D)10%T`|n{dx4N!?omh6^5`H|L0Q91!cOW?N;Qy1h4#4lDkS(Uu~M-e!`dSW z#p&ycz{_THM}FaE8{sn6CO`fbGYAoV_RDms)@bSD-mG$>(DhoqaMY?qwOwqL>$4c* zRWIVT(u84pf)#i18BnU(85gV=;UR+v7RqEE+#LXnsvOZmoYD{V>g3a?v7)$dp>eS8 z7VUhu;;$9l7ekIOcT{$n`^PCF`q9FYvY(t!>#3IS#eGKg3aX)ha(VN1a;|Ff;j?^y zpkg;cD7hL>9~Eh~fYn0z!k{Rd*0+O;R;MqG)aFP=(AuLh&noi|p?9vfU#Ksil$3s# zxSwQavD++$Z2j5JAswo(?p!Z0*OL0bKhN;H1U|8dq)IfpaasE>?GwC+QgZBa&ZJtK zVV0Wrk;CN2%PqT;bno>fUl9FS^``l&L3VzG^z#kAnPzY298l%_6LIa=z;#8Lb@n@J zMn`CV)rqcY_Cw(LB(vG%+k(D##00!)=jC==LrSsf^p%xvf^ERkPN%xEEe6{)nQ-LH zZL&iIIRRhubcRM7zT1FM<|t>31#&uW^ma|OF5CQmNOBPu zjLOW5B|hB2&HKf%gwOrh+M5>TqKjTJr@+iol~BEg>2$TEs+%oAa@ypJjE9FEp9Bpn zvj#du+wk)(Ye4`!?R0IDgLk^^X~8T@RG7YmMv_qlyQmO59W0d=*$ zy(w!d`{Ateml9bh&C_YUFL$6oVXEsOIl>~SsEx$s^w9g-7%L6_QhRbp^i=l1lVISz zIpymmdc1f!jKaS*6vv^qufXOm`qi>pShP&$v0@)WeMg>jjulqK@gAUaq3=6!#S>cV z>{DDMOYGDkl*a%qxx)?5=r)4_*<-z1UUuXpK^=yrOP*S9IOeF(bf4shDz=N>b$6+Q zA+3L5wmf#~qU@anV=!VC&G9nh6$Bepfc2A1i;@-j`ITdp1q)AcJlX!Dnu1yFANzpc zgYgb-3X`aWKF`9Ff}zTEb?qm8$geJyfK*nm7A5FThI8SJ_Yvk*5^bf&F>CWPl5I|G zEMV~pgM-e$WzO$1>bfY;`x!tt-gdCI<74<_SbMb-G`yjthxP|jUniEl<|mcEv9u+; z>cZ$t3WW+Hudr1+ce5jCXe&o;j40+Y%eQymOh^yyCw)jA8h)zG#h4G{Alt(UBNnnhVURnu%@c*-jAk zyvdhO7r6o7Yg9yruO3U=(8c}z?PmUHIeLmh7u>Z!;|({0U-u8e&+8Kc0oi(F-mi{= zzfhHhAukYL#y6Ty5LmqW(kojk#$2L@+8W)|pX>03qvJrI5=4uye0l-u@lrHv@;k}7v8z?2&{vu57-iCAR?T&FI(8~ z&Dxf122g_6KznsJeA@@6z04%X_I(bxhhTOWU88=$5Ic7z z0AC?V3#X5<+dc9DEx#6Hb>{bjyrL+NK1xTmMmU~*NbTp|121!>V}^@^=iu6*Y*;cu zT32!E#;Lut8xa2uvhv2$j@nh}YV_U73Q~ZKCfV;*sJuM3Qqn0;Hbq# zz-3ykk^C~g1XC=LS{@r}Sv2t=o2?{@FDk=y5l-93OxL=_!N(> z7I+zk;6Q#Wv$1o=E?BJrYpp}9aaye(BooUql8{4Dg5_@v<8XtCH*|eq&1of|MI)n5 zQ(bD-HfM3Cl}31~17tUKR2298H{J~W_(!Dk*W%k=m9D~v*#Pw$zGizt*bOX`F(gedu}KX5_)GX)Dhb<+d?{dZG;&AwABy2rf!N2 zXUWvqH}Z@*)o0|Y)umhLDF6EWKc*&DH4yBvb0o}qPC*5RxwwOOG?Tjp%?5rpf`v#FEMrR0z?b^03rx3p(<+ zzEU#iNi@~j7tipj(xGfHJ?}*&vLj=v9qy8QgZVXjg250j4G(8DJ5pz!WrZF19o8~& z)m~9w(r?TOCvcA4QxD$Z#tl7Ybx#5hBMr&STN~Oub*Fy|aKc-=R;73U38GIVk|pen zVlcC@cNcs5B5Mex2Na!g6Oem|E{j|$9KbWAgAIO<9L11=Kth|t+j0*WUZv&wSXkS0 zs4N;jcTxZ;v&2JY+~+D&+E7_h0yC#nXQF~@AH;rNU8G%V6*@PnLct#9Sp9@V-vQ%@ z49Bz&ZdKd(_8Cev`3su6EdW<>^HSU82=y`gew4#+qUd!3S6~URNA7&%e2VI$>nBv~ zx=MB`m{sUh(o_$JadqTaXV$?pzlxvx6#>cg9`H85<=ZE-+C=gUTZvbH0 z8S5Khj@zGl3X^=5_O_U0uv2Nq6%_r)qNxk0bFrZGRKYsqs>fi%EL$_Nr)YAQVP%Q> z+_al<2G0<7v3SjYzT>^Tin~R*nD43g1~0P7QFm(NVwLG~z$qyy<#WOrse>xvnSRur z{~vg3U;PblQ49Zl!&~oO0s%v1?-2q6Lg*|L$-3;2M+(H zT(wPO+fwZZw@?s1Brv^yF$rAKxrivP`VOk>TW zV___Ie|FHNiXR$ZKfd8_jr#uue-la;DD38-v9Qac3e2+;@Ov^i>kcgbvik$m&!pM? z;mQp%87fCaJQ>qz^?*)~V^G@o6!w*4uwK4M+N-p1h=jUAhzebG8!5JGS3;PzQWD0T zlt#JC_BG?N@`}pdqcm=hxOR*)r{`^gH_=TQEg5eyWrQ#uTMFEp?zCpxwrf4WB5rt> zeQCO2Vhw$Co{(Kc>_b#(;cB^L_3FGLk}Nn|2{Gld;u@YnCq-POX~S7)--|VQ@plsj zCNCc6Hf)1W^H;SZ{@SQ#RsnywLQVQkM5ACX?XqucA7T$Y!Y?eEk4ki#{?r~g{1Nd2 z$%5|!8smR=N5aqj47p`s&6WQy|3|raoI}A!+53C1ZiZlS-h=SuMSln@?ZJME6U(K7)=M-E=8P|KpZp-Wy?`5-PRYzNx?HV=CSv`u)J z5ybr|7AYn)^YRm}*!}=bs?I6FWz7z7HIN0ZS!l?62Hd5cS>A$>kp`VOrSm}$cAk_Q zi3(yTibHF@GgH|DsA=IXytt67kYLK8crop~Y)IqkjnCYMQme32~P!$t5F zq%apSGBsh%59)*|o=ZmuPoCU$wTm!J)+nxX$P1GEv51);G#ZXta_+Th!(zR*=+^;8 zKv{F(QJ3Mz{L~Xf`%ktoUOv=NSU&Q1qQ0-ZT!w&}vNwyI!4cQNy4ep^GV2U3_NYd7 zcIdWu`LaKgS*FoO^ik&N036r~8wCfn5(jQo4+599kwg{fi<6enITZ{+re4%?iV?`GADu zl-FPCl{d$r#pH?hf!Y|-5u?Xvb7nNjyuP08bN1Jr^#Tb=tv`}b&1AKt;B{2E-t?qe zHvAD(1wq3Bgv1F^e!8r52JJ^e1hXd53+WZ{3+co3L+q5J z8FoV%XB%qVki{u>aJ%{oddvZQ1M<=t^G|dyIG=XPa);_@|5Jvz)`9u%f)Po=%V~Eo z-oKm+V$bS_f3|5JC?o&5q5PGKkLjJ!=pvd9(%)j_cdXg|jj;HSF@!uC`9bC)*q;{? zo`9!dxCgfOPJBD$^u+qs_2s(WU`5DBm6E+Fn`o;$%$-qA^YOW6#h{fwit31z5P(ZC zMqty=IgrdYXH^MPaM{6$S^M=Gff}CN{1e-7cNtQ+=TF4) zgRp#^9<=FOAaIe_l_rXr8?8hrG8f?EX$g`%zfO}qd9qhK$i^p>_a}%dnm2SzAi@>1 zH5(qJPFT$HcS-(9MNcMofp-iv92zOZZB+_QJrzjHt7*T&Cv~%n)OfLv@$zO(pKMf? zC)vF0uC)hZ5pK?uHMM+>Kz13Xd&E%>17F*Vv29uBU11pe(Gr0tYn3~{VSb^`P)9qP z^%33KjS4L-9-QCgUy!uy0yhb7$Zkq7BEnyGT)^H=V4n&zZB{g1MC+VslpJ!_l7^gV zp0WE&o#^gb+NSq6_&CMO6t4-47N%R4jcL7}>UccJIH7%}RNhy^G~)G#pW)?4n0Zq+ zO{&U5a0nQcaw`1_PiCrk;qb{N9|nS50;4CYLs>oe+s+Md;znMDBRVW|N=*mDB2Tla z%>q7xQ5$1bqs6|NCmytz_HnnXIK63RO73T~C}Req42EQr{-NBk!XmD{ z`?%dltOFD2s=Q6I>sW1ce8OMV$Ddggujk|)qJ{i!S-Es@d(9cs(3J4B(j z_|+PCV-+t{Uo`36_byBTkHZlj%O*?kM>Y)Q&{wp}X!UM9=Rzcv-&jK%$odfxe*-s7 z{!Ppo?I7>2pPVmw7VsJI9rx&y5hH|s`o?P&o{hXF&nS%WvW>3BJ zSgE&IA+wInVmaO`o?n!f@++{_km$z(%@O6DkEu29#>sWAil}hq8r#?sbq~SL8kI_w zR&Y-EUz+0o2*p&{*&Fwl0&!*kcK+;Ly8O;o}L7YN2o8D$bhwe6>Vi z)%5Frf;T_9yQ|?YBnPb34dzne48sadDIqi7Mv)}aROmzoeaanqg)P#ttI6n%lG zX3LO9rqVgZaG~29#M7uX8<@-#Pd+oDBM~zmxtZRaGd}#p5+C=*ECu!uMIA;a=j#SqwGI)FQ#NpkeP>s_xa#l|=pNg`_c>;N@HhTFH^gh02iUVgM zqj%*C>m$1HiSV$>)a30H0a8Kl-+xG+8LP?jd{4E1q}o=08D-md+AsAQ8Df+_1v6th z0q|Z*9%|h-2v?$v6Q?!%sUP*ino^sP{O?ruao-F6%0>Slv!(4*U=W6vtOazls!1iJ z+?J~QNc<=4cnCd@7X4D?c3s+fDOR59kAPe!$U<0jV(91X#DCp-H#7E9=k$|MLXaDECBw?CEa* zqtDeZ+J{luc=m*H+yO3KIecI3-2?5fElt?{kdP!oi7k>d-yWQS4fRwspHY50Dc1|} zQLXHLSy$pX?q#Yp*rIK%alYY7U-dfz{k|4PFj$K_OxpnPlk^GTO!7E8wRG>~7gbI3 z+Lpptob?^}XgZpIsH&+q#X%s{st?3U7#5f0l85-Op2(q@uzZuO9`LFy5^Lub)jM`3 zbFGz#3b*+Tod@6EsLX3J+FHjqhvczZjmP{;Ic_P3Lr}QQRL!PRq6{-J5QOI=)%T7c)j6#`7%+i@2BJ5ZTU|BUBgTTbXh)PoCl{ra!ss> zk-LC6tLN&PLqtbl>uT8Oyl&@Ao_YP_-81!qRx>p0rvIHtc;Akqe=#%vOcCv~@td4k z29B^=z&2sLXxOl(jGxUpoPQRA0X!At3$xGI^7oJw!$qs!$f-iE_ZQ31HXH|JYCD&5 zY=h{0!(+rY6NZ?+%_D67yA6{$6ORv1N-pRsn85Q5Gm~bC!E=4K{|k@O*RMZ65UZr+ zC2h?d9l`=&JSV=45<@{WSstCc2Ggd~^|a`Lc=4KOSNv^%K3!#Vx$V-J8dyscFxiQY``cTI*$ac4|Xu%X` zl+3fkulVbZLE}z8jal|Pl6+ISA-$elzX2(fHLf`l^_h%3(5qmX`QbX=+dPWCK)N9n zinyBzbO0J$*W=@;@Jne!$?(ICso6uWX|IJ8g4*jZq}~I^Z@Py~iVx*+;4l;K7(@$v zA^q!+8}QWe&`y->cb(sV^4nogmLw=Nqjcl4>Y=mFb`aSp{JqDrXM|f}U6s zF&Nrh;Q8i&!p(4C@_W03Xo00!Kv%gEjMZHMO|TOX&KTY=RO(|P;7q4-N&fl5R0vFh zZ7i{Ug6yfaqHepN2d>2M5YyD&wA9&IyRZ--Lt$~p93b`e&yc8D535jA-e{`{U@}WH zHylj=fxwPSVecfi)J7Wacp~1F4>*W{)(#4HLiSPP)832LyCsbUc!#i?jh5%s_fy6m zX^qOFLwGeXA8@(92Z?$<UIu?rOTzZnmlAX(0S4|>eDNNBVa2;4M)W5IS+^}~4m{!^DYh~vHE?@F(zzp3 zFT)eiW*BGwc4Vpnc;m)8NZ>UU&%n3+!#x;y8zbIBeGmSK>)7@H!_Ynelg#OyWH&pw z#dbm#-m3}b_1~BjTm7ipYZ|gC5Vh9?k&jI3g$7~l07|8vmtI44ADX8$UNikD`xf5J z;q*WKvZ3nt;CalKZJ_`Bfpu?A(ZJ9a-4b-0V1V8O@J<+y6DIZjoh9r5F^cb>TFvxm zwHr?Qz-5OdxF?;hwhHk%+04{8M>9vMZjRS9u}+#ImmSAXXZRAc7`PoviHTxD0T0=Y z6h7R3SmO?AbE`_ie;vMGL+=w_39x0kXKM^Z4lIkEtr+ifJ|(hx>5Bt}nQ`@ZI#<96 zrEjHfAV8UYb6*OuMr^=k+oT+m31l5iZjnyGVZrP*>UtExHnCp;UGt_i=O@tp5)U~X zD!#eBlJ#P>2t*-nej!mn-^K&;=2Z6jETcnMpX@fk_!;#2X68b`wYf>3<5u!h#Q-p& zr~6InN%|1ZWghzSd7x^nXp&W zEDb#@CW+VNM?z_w4UMyfEzA1ci6GsKmL$s!3LEJpZ~IKVxr6Gd)FP#h5_*~6@6hpi znbI^PqoD8ihVU<#;n&ENF_}JC2{}Fk_!F?Q|8UswT%n;Z@_-i<{-+LNHn6C-P!c^i zcMNBMd_q3H*F7Lvz&4~BW(E@|ah*bdR5H9*(;2vR9OjF@4sLSM2Ok?9XfD2D8*xcu za%S|qXY!~u>w=i@*!|?8*>^TiPP=-lv+duss6>g|4+QOEPHi>4es+jz!Eb=i zs+U^Z*dSYgsLu_gz^Ub-3-Un1ti6FH#?Gavr~W~E0Qz2LM9_Xay{-K4>T2-W33JCQ z$P=ebT0s)LDiSU#;_*N~{gg1xQruZ5&S6FNhoaDyIm-|ht*IU;%t^8p655%$PQ^mc zlE!Zg#j#r>u}&OU6ABnIJg+&D3_&QQSoFMZ2=?Kvcoag)IMFt{8z`i!mN}kZK$&^9K7mzBwJQ^*YD4c;?xAe@Mj+CtfNk7;`WG?Me(>GG> z#e2L9$1{~i8p24_*9S$QPBvHWlZd?bLHDUi^Se4F3sqzZFS*NR^%H@0BpLhNb&e;9aZhTzD-cR^q>g87*G24$i#8XV(ID@E~dhsd(7_7U-ocX^vIPpIH; zySo)M`a@ZzRp%km@9Bg(M$sA(n7(nQ`HbkA^Paj}W{)}S z^Q$e>&Z?ku6u4FvHkzqHJe>K!RZ8^c$5OX_P%cQFWpZo7t(Cl7}!y7bX8~0_^zO!`3~U!g`sq+E%-1`p&%lXn2hM z@l;Xh5zh+M5mzulLQ>-dIXVF`paivNK?}FNN8C*&IjZr%3cJ`wr;JFW*$2&%bk=$P zZ@6f>&q*Rg$;*Ggy@jtEzVOy%JdnQPx0UE2{`lc8>?B^$OU6n1yB zGO6r(SY*N%-9HlNJ$50qIiD;4M~yLGHwiuB?@W|6i{Bg-RdQKD6gfb%#3$K8Yf!wTkOH;* z%rVUQVz2_@{4PPnZHbzv|Ln`un{(*2q!@Hj3I*``XUjV1-IH}P|? zCW8n`nojIqn#lFsTP9RWk^nGU(mpFpQn?o@6l)v%=L&mpQ2H`ui8HjZwbR-=J`Dx8 z+>=k34u+=uanc=(E1*rhppz$zDn}T?_^a~>xXZ2D-PSNjbzz;K`-Bt6sIW#(Ca<%^ z*x+S^0^T6<`_=}Tx`~QDqw*`DMHja|DBJb}@7V39=XcbKQJXSNF-myoV$0o`gqZW! z2DuUvBAyrvh!3qSAuPsv7_QFkFYr$5%!F^!hpOlci(!L-r&^8-E340%1VUbcG9Hl? z@HnTaZlU&ZM;|bcu4s!JWf=j>u72EG?{%-{Oky1j#dU>39Z!i&3LR9XxjUFq^zcpN ztZAy$O`V}M1Ha}x)9?Fv-i)4UN-Hcj@uB&pu24^@wt-0V2m~DuE(7lypJ_L`87#!j z*F{d~S9Ob4=WeHbko#__D(=7k-IYj`O%;1#kpcFHAOCqO8s01#R&!r^%(X$IHl(?% zE-x_>5kshW+f%x!6r5X#-040%2_mNAXKM>OE!DKb28Y&oZlU2V!#k1Pq(PaYKK$5* zi%auRDR`q1xijR_1L6HKV`z1FX5CNs>!pJ5+=1BP(M8;BG%o1)*`y9ji?U6*fObP% zU_{By%wfr1_NGOZhGuPk_P@NmYlp`sgjV%tjBxWy!#E9d_;qw__#z=EhJ+E<-hlV9LXknL5C znXo1)`MG;dePDi2(dEr?3vxE!B85#y+JX#OpP){9`p2Vfoz1cVQOgRsV5SZJC)Q;D zI<)P|B@FdTG*X}G@V@{F1?m||3E$JP>X8Qy!G_#F z(2L_4+P&dWwlKa4mMenso@v%mqF`dIwLh5>uUjdd>F^9@i+ z{4c1^sDlh=SR3?F7TLh=fay3FK#ELkgpImwOdVqA{#QcWWf#ChOk19wgHQ* zO*{38we2Oi1&TR~JULkb?nn#wYU&qlbF*^BY0k)2G(S4^)us2^FApXAatZEK&8rUt zGc*Q14_0fZ){WTCO6l#IrIU|&fhdyO$T<>%9-f=N{-`^yDUNpA)9s2S z0$XERVi8OQ5C^$D%mfbI+4E_=ojtQ$>}`v`nUa@}Z>9vl^FzSp4`X4AaslfGhr|Hr zjIbP7M;&L;il;@8I3c0YTXIeF{{Nl~n7Vu#@sq9z8H|TxS1u02txX&jtGnmwQ=>*1 zrRH~Guh|c{ZY-h;Ywz|}_Um(4!X@+#7}j3if(?=i(FkDz^ixdvCo_);8J%0Docd<|l{32zYt^m8KlhMuY=nH0Q4$F`+@WtGz|z3aqOW*&IE3_hcyTQ5 zA%{JOEB-PcG6@FTl1n#sW{!-Xu|#4B!AP=U%b_+``ij+#2W;$mKaaxQ0zH>1z z?~oT_xvW0Bv<;&lyTjm1&MB;)Nu_5ZY2hnxEs_P>{OaGIDAXD$5;x);_3*Lu^R@GS3?hA*sSsBscKJ^?Fvx5ohxRBZ5~+2+Rn$Q z59CJ=F=N6S(%z|~s}Pc?GN4Bry8_JktgBvPnT>E&w2SE_&H#EY8e=8Max#w4vpk6j-I(0Z2ie@{PV#22%Mo& zS~8(0d13NJ6k}!RHQP;iMQ9VlQkfNUOy^T+gui$%d^DQ^VA1RNOBm9BEs?|{COkrB zF_F1^v5mGZKkkS2(E2W*g$euOYeKJxoR#Yp^uui6#P+4In8lcnV%=pAJ>ZRg?LIBW zG8e#2lgg35U~QR}p+4X(X5>(&{{B^=R$#MF$MQ6f$?+r*zKL4no+?g zt~ozsj}aZebzdOdpqdj4eu4dnLCnDpDe3PIWh+NfxAz@vX`BoxtgHNTVTk+WY=F3uGUKZ!Mnt5R?3tE0Lqf;vx@-cEQtX~(Nux2k zrt$&O1+LC-ARo~mB;j&%-(oncRr}FhA<@NLsyA{!1wZ`Fq|-~1@Wy`BXMyQFQ;YLT zZQGX8(2-*C%1+<6eenI=A{Mvg6Jd*Ehm^N9^PLLhGI`0kzPjANnHk#A>nKLM^YPUn z)1i$Ymi!4*I6yeN=a}-b{dR>pnhcY{p?;~(VRdB|gV$WRm>xl(K2GFu6~n_&qBL}& z^fX|Se7Ex3GEnJkOPacU$W4k&zi5!uB7nE?byfDw7fV_zFISNKWV0psSme(9_co^( zuc{z3JmJo63oIgJK@Pi+iW2SC?(tU{jM*EmOp_4hvkzm;x^^+YJ->z)3MH6t`IPHd zL#)n4#YVmV4W+O5PH^R816228A~*WTPtC}5Uo&#Yvmx<9Zk_|D;$S^)vr(ND^OgrO z(dT^JVuy2n*I2&8y#d%1??$luwXn*s$DX-tIj{RA)X-WvA5vGjj-SDAUo8>Es0>Yb za@y!2c--?`z30Pp%rH^Yc=ZY*;rLs1W}x!WyLxkv@Adm*pRb;_KX8-K@v-qy;&d&a z-yi9--5EKj1FVg!+^$ny*QWW^XgxLls1{WG`OOisu>Exw?fZD6-Yq^OPM&S~>7K3F zjO)tyxK(0*++C4XLGv8J9VTD(x&LCnyhXdzd3)*L%}40T!0CtU?Upu?@|@D+wK(}I zP%go9f%yNn$mVQ#Sg}qAT*`D8)7!UH%4C$=^%RQ zj)ihWjOWOoa5TZ+l}LVIl-yJCjM8T=LFt&S&P>1gU&@nPkd;Usl+VCrU>P_kXqDAO zWQx8^5J>qTx&Xr!p8TLhgt~jSvBY%nWt@i&$iZG!tx9mB-4S=)oykRrBykJq$RPfH z2@cF^olm@b_L1sH*|$`lJ5pm0hBcA(6_h5S_`)HO2s28!1ir}FQk|-0zJOqF>^~uM zKw}>Y-J`T-YI3e=faIF)`Xj|t^W}GA6SIVHK@tF>^3Z8%K!<0Kh#72ze zIwCsNy3kA~`8cNJ@Tmh@OYpd!1TfE0(OqeYOQ!$p139IuP}n9Qy^qQEdu;AAak7^y z;Njx`7*go31*Y2TQH3w#fli}JM<4^TSc^^1cegchMKG1pqP{wOsXqw5;zXQ_wyg~R z4e2SSME)a}qCeRylvX5l1zh3CTb*643gBSBtWg#~u>h^{Agn;;hC;Ql?ye{V(r0Pi z^`slVLATYaQAfMn-E8INlH#O@gXzKVZhOu2uJy3C^~7HM=OW`>9Yo46-j}pAX+2QM zI%63Ni1hUO#Tj2$ovoUdq@*EYHFI8>i6Qxl!Oy$#>Wxu(v3dtSy~?=YdJxdv>Q`ZO zs^t^@aTMIWdNx5Pr|dU>AfKooB*_AbrX8H9#AbIDuoSlK7k^m$D}O}EmWy!~tw-T4 z?fIH{e$S)I2+LxbJ_Tu}@?$D2zu8bPuJkG5R8ap$AT7+(fN>k|1xGzVbvi;80l zb5z04-~ZsRjly%tPFA&nb)rSCcy46(EsO%o4P7N2LJ?qlei{>$xn0O;@N!NT`aPy3 zh)Td%^HyI62nbmbWnQ8&;B+rU%82!nOOgb0QD!elKM^$Rcg4lfjggXvQ1okje&bK( z>b)T-F4gx%9>^e21l&bks`!1?UbTnk0!#!>l?xt_zjFZ)E~!r;J&@LJctyq-yj6x; zxCPM+aFr9icQA&xl2^k6^DGoV`Y=&_?WqK=i#40QUmp8~(YB;|ax?EBw;@&hj>(K)l3Ro;tRfl&X7NyHdejf}FMtNv<6YO_Lt;ow$(N#! zJ=MlxLL<^sDe~w5dzKP=EQoX1rGHRb{}TuNS{YVEJig$IYi(}{FT@K*@Odd?p*R7k%nOTY+XleZZ(fCgTwTlf^b z0n^s@5GPF6pWR^n-L@~ZZRA8L5`m&lJqZEnF;J=z-}CdK7K&ZP(!1H?S2Uc5r(DudY;jVA(JaMjBc)JY}#T<8&GXRgwe{ECVE1#mrcb{0v` zyoBvV5rX)0C9k8ySh1N_A%&yD**owL=SQvs^cVl?6Lx!QMI==ZT0{wWp1xxyrm%9f zcXP#d>8-WamB+zkXs8Qn65379q{&erwSYL*2slo|sSi@}GjtM?COAkwjK5*v3xz#> z9F7tU^0Mbl&=~n$-ND+XU?_iB+aJ&k)MO2q?mEhqyB26rRnm-QCWsc`6%sJ}I#?vm z;O8~|R+n zsZ_BsK+_F_^Z}(rqWGB6NSH%Ra&iS)M~WxE1ZBprHilfL!6RM&LIUkjH<+*%LV>Yq zPTE_k_|hOX0wKm5%DMn03qH+13Vvk+hnLaz6f!eT!q^`)V9Z1o=9AWK!DRZo)WZ-vLpmiH}a$AjKbbDW8JHgB<&`GG!u-65rv+) zTszey@P>+W@OQo@NDYSov?lb=P!yMl)7Eishh3ep#klaaQyYx{Ne4pC8ON(u3st|L zN${KjN)Ukcjul)$g|Z(gk1*N@v-~6l*Ke45+`oCl9f6B>;@0 zD`l>lVWkRyKzELp*uG&Ml7b(xh<^r?q^*%}L7zp*aIYvy^H1lJ^=RaKqV}tn0!5HC zCDCZcJDKi2sk!#vr$#g?dmNcB$v)UIa0&=ma;2g!>-lZzmt&>tmZ1u$4gznm(DaO#|F=fY z{-5atfaBk7h7Be26lR_#?A6*;9-D{AW7y2YGSrM7(1VB0W3jPwBG)-iC1SXcVn-9r zG9nKrMae8T!?=quB8nq-zuoI~Kiu!{*XIxTyk7731yAUXxC-9fhdo#z-|%GDMvT6c z+$!&Eth~|Px54c+_6^*fm&-r)M@*S9wEE~K590ID1aA=V0FXis?3$oCriYioUwLlo zyg_>(mm_`=z?Kh*G7Jz_GyVE4n+XFdYg!d`VRZsbkt$U#X`;Hid@pwLXAGaxZyufD z+v`g$&_SY!Mz0rnkoV@hsKcME4zsYneXb7)R?<}lbM^3?-p$V(W2lMyN#zs~?c~*L zHNHSD%3)Qdi9=7?)*mxh@u%0nDv!qwJ`uobo4Q#rPC(0CYi{@m*)bnXw?0XUAafMO z2~kchV7;ww>ymQ#WHtLCLIG(nl~(tL3xi~ zFd+j7HauVUhFZV03{LIh_dBb1f#$uGZph ziP3hs2go2#398YXKW*k<_QE4srZ!`q9W)y%C?6(9SJlHtJRVvwoCEEfYzJ)N)bp7} zcCpHW-M12a4`q&ZTpC2l4$#?JvoS{DDeiTrT*SzsdY4)-6L;pEk9qDz5)igO(u#D| z^xQbXALuLo4&Ql<_4u`d8_crt)&u1|Q?nUGMK3xUYqZ#jw+DC3c^%pL<8ktjerUS_ z1tw^*Al8Q+!)ygUH0dvL$XQwp4^k!(xM6Pc=pVxz_g84E@oj$R>*yi~LTqmUFm>5; zNa99`(NDzim^vV*K5E`xr017;9OXCUQ$|&C`*==E@yC#FE5MqDeHpy5pq9{Ir!jyc zC48FvX;Ii7nXDA3LTM}DX4AGtL8njYTu%}SqjTb_C)R={OWHct=4aFv{D8S&wj_yF z>4bb9x~!(BGFMteYP$m=4W{(`gu7WFu2<=KA@9+dx6_rP*qLSuEW~<^ z`Z+Cm`17)G#c)44c_AU*m=};b-VAZtu0`&f>+(uBdY9^uV%3?L_6AxVVJ0`F`(do~ zm#9(cR<(lkeAPO_%|`KdU}3BMEExaJbW5iHQC89&nxvi0m7XhIN7#lo%NXVBdFU!~ z6>h|5qXyxlB$p6V<$rh~<|(1Z$5qSALW_)bNDu4@hD1Y6dL+#_QRlp?s|WdIS1rVQ zvRAZpwL$af12B$krn;DGk-m@Hy~YwU{_K2zNsxGf{S97lBo#1!eAnCZ+9dIYm^bJm zr7o`9<*mGFVysox9+6H)JK;xmn1+ox2LqEV`M*cHZMsnoq&`93X_$nc^Gs>UZ+so< z7uArIJ%Hd@ivYrEu05{!ZOujjGCw7*6{I_>-3Gw&Bb>&GEL%o`Ycc;&$P`MP8B6f< zPevWs-J(gje7%%a6te706|hhLR|V#%BrXKD zJVNLDbpmTAq3H+!z@hzDzyN6(*Z=@HKtV=D^sDiIZU4&x|G%|B9n)Rd*UJKMQj${! zfI-4QPzx!UxdkTXR%P;vI{oe(o7*@zyLouMAF-kg8QA{#Y{SD*n0^T-a&NkPfBOZ` z6MDi#n!fwI2(6lT&BogO1cjtgpRx&3Z|An#nPT||EAXQLxvLB%<9L2($>D0b&P$x1 zhJc|%utE>JpZGk89*$GT*gtje$Q%)0>ajr$IMW>b-3T`hla_2)48gOSY9Z~8PWur2 zR)oa%FWTgwM0|0MG-_DPenf(W36`I5>567yulygIHQ!S%WsLQ2tI;JbjpNx96dV_Z zu`&TJ`L&iFmF4WFlKNYWSq48H(PwoPN9Agmqhy`6tbKay`T8Q0ya|iQRa{$>A^NmB z0RWLhNfAL6w~X^lR|E8c$L>psqfCX_V%K`K;oxZ_;%qf0 zj~LpwZTJ7IvPJZ%h=~=l7nSVVC+FXHBG%sPxLsmV5o(>CuL?(P`8> zg%k#){**z4289F%heD{A=#*F}1Y7Kb_8W}x<&}#)mT}oEaiXX~v>GgbSM)V>yUr|D zsF!xa620rl+!K|kC(DDpenTPPiKb}w*?wdBtGEm0PES4bF2ZKMB4cqy@ZEBSho)+O zzd0F`UR!jGz&DTiWhROKM(bw`Uby)>MH0(xA9H`BIbPzTlH;0)O4|b_d0w`()vF7^ zjg~_U_tDeRZbX*Pq4w4_DZ#ClON@r%8F)E#w)_!+!xhE$(kC8;ueui=G-EUvCF}NgxHw)O(ezlLBG-K# zH%91Aws_Yz%v!|@znr;JK&+HAHEIM9&gAJ7Ty%U)L?tPSC2sd)AYX>CJ#9J+Vit z3Fw(M8O9MX&fEVhbj*mzifaurU{2H55?nKUmO4W$OY*2fz(@FwD4w+`_BYr|=2YC; zcU%>4x|&OU?QuB=(;{kTWZM{!mv%k8WrB`@K3&CN%?!fmHaqGNd-GvT1G_ZDzFc>) zo1d|#$8Wn*O`SY_;iRuS^L3%|n=#XCl>31B_PwlEc~i=|f-$I~x9e`>KnK;v7jmPBR3CcJbJnHXDCd`vLzT6! zY_o6*3&~?1e?ghugnC`Yt_d@g2b#PdgAr|fV$rx zoiIjd14#K2(v-ZX=Roaeh*?usMuZ2AVIWCv$I$#pU&S7hm$AMD7gsZNu|w?!u0liO z@H)@vKE#IML?a*|U5)pdVst0%UnS9Z*~~(Hb2UQd++v@D7USDCGiym;r*w zV}v&pZs^zq`{n8#}|fl$XQ}+Yu^!Qx}mRZcmm8m z#5VA{#Z+9|&a0n;bVZ-=x}oFPpsVM&9$zGfKA-Wsp^vbEgH~C)xFvu*hbl_WQy^pt zv<>Fi1n`z4nCubkHx*zLn#xV$0;2E-KWsj*KRbd9-R}|tlSeL)nR_?v)kYaGCzgzb zTmoplL$DMD#rZ(3oz*Ym_9{ZZe!sFJ@>e8M0AyB9!lUsc&@G+)Tmo0gGUdjeS0~DR z^{oNs^T#JLo~`Y2Yd!$l+Ltk7Ko7wQfxk+AWw#_x)EuoTf8%*^i%G3k0NYvY$HC2P z!htxA`~lC;O`$pLsk?Oej%klx6JvvB_RU~I>Xf#Z>FuYV0@&U8!O8;?gBMit)Hk_%%iumW+nOKl&rCZ}1|PB3U2D`(Cc*^7vdlHu?p z??jxzR4^~srS(>AjWLI~_Xd7e)LMWiG&qINB@5qfDhCLf<4{m9BL5c9zHNn)?923s zK$p{h833;CUTSFor=LrX!ughBkge`p%tBWaX_~|U@B%{1VG{`?Ya&g2L%p7N+18zY z0%W_j(c@!Ch{DVqvwMU1E@#w-A`(JwVMriTrs58@(Z3D9c&Q`PUyrkGlFB_#V+&@x z*P!6vkN55bMdSq?&+_pfd-WrPb`jqSb-DniIqw5+$|9_sA5jkdc1Bao^^3$`4= z+UmA5^dcznw7Ut};|NGKGM!Ig?iYQsx53RKlJtyvK5@xmF^xmM9kq4u9`+Ldw1tx5 z{bl1{-rl><$j61Tyj)qrWlZb|ry~2&OWhy_(c}CJ6{UvN|b&k%}A`KQ@TB?XfY& z!?(}QT`?*V0W(Ei8H-`eqV-WJp*A#j?Sfh@Qc*RM?>NPV>Vp6ft^vF zB9m`vQ;@e|DcXWjhuru5pPJbdDf|3pihjw1D_`0|osS$%Kj9Jj5MZ)mAVzqT@I zX!yYmV>fEFL8ET}?Am2=&g32E{by^N+=8*Cp15Bhd9&X-{S8Og=I-Pv8nj3PdBpTh9G7wwD=gU&-NdjD% zv$jS${}R;tPJER553*Mdw++0x=!Si>7u{KFiLRfkMxkO0KbmWtj#1ApTN!r6 za;g>UG=Ky#XjSE45n&NngF|I19gOym6S+S$2>VL!$qyR$yYXGI%HGf{Ns*fE;95iv zjy$7W1@7Xk%ZIpr%@c9UJ?Lm!9_+;_C~LS$*h%e6sRq)h&>l8jgan`bu25{lwDw3s zb^5#@^s-sslApiYL_CkP$xFD#3PQq|`7~XqFPdn ziFUkM@z)6MilHQwIV!u%-gAnGzBjX^>?Y^YdaC7lai37V05$ZF&aYmNPE}3beHL%` zRP4ryB$pHDqod5`v70HM85CvHdbjYyoSY_@JduD6;gnIM7eWTwd z=_B3x*JTz3Ra8*%emHoz= z(GiAUb-Z(meIIl>!E841I%nMb=!lyT1fABzYFeUwy3u~v?Qic&<3{PbIB5?7j#~os0JQmr)ubb*u5X; zi;c%^g_U3a?ef(5eXKSH$*jN8meQ5KM1bX&neBe&&t1DdXxfXw?h4=%gC}FRk+3p? zp}z&@P3!hJ=ODteTo}$L?ah`vcB2kvM`(=Un++Icj&jCmAgAM6Pv>~cqRp?nBo}eP z=*+)yB>P)Sjxj9yj`;;N#;YB*DPR ztN;gT>wmmv%?m)J9j{Dq@J_Wp&YNY43Uk>FsVY!<1(@|w-LjeSKDG7BQs+w4qb=99 zHD*m_-nau8g6b!sI zr+hibNDwcBRk&|ObsTK{3~cJ8UoNeIL(gO$E%G7KcjQUuSYkyQ>jpU&_`Z>pKcctH zJjO?{#7*u)d-T(iJ6!RMY%(a2J=D4V&5oKNti`l+`K#6wfi)sD)hqd~isPbp*;V3T zNb6saEsvA>PxeNFF&HU}=5Uem0+J0n!1__9S;>n0^un>yf`z9jfo%7mnu1wPn0>&n zfdmIPg$XnwpC{o7!BAzo+P0%!loyu@Kq{+Ovl2`P!>Mq_+c5JoskYL?sI~bC=_V%* zHmGQc!9nMKk@KsJxc-yp{Rp5NYu#Jf@-cigthv|<8d_7*Ll1+}*NG#q{z2t$ENzLP zIzRH9LZO1hD{PgAs!<)YGuy*O7rik2_T0wgc9+9fy)>_uv$UOT^3nfHOid}mW+)lL z=8pj)O|+QP!sfOYV&R*U%VLW6HZy*y^VbQKdNRWsC60Z_^6l9*6VgNfK_61fM(pwi z@m4N0Wnpfe4I_xchHzjvLjF`zVgc?l5Tik}8ggQN6&9=~@}LFo+T$OWP2q5DzYya$ zI&GX-^c)aA>@*s3e1%gg{E*sIo_P6Z-JP=77ro(;2Gl1bIvfj1bAcUEGqEi>*$Seb zGx_xCBsbuDiH^+h)njQLJiEQUUe6mT!$?u+gunD>yy8am>-sMEad|{2AX|sR``MoV z2fCsl-0WDMj}jAZedM=xN1QU`(;PJXb_8STA~-i3fVWfif|}zEM1+6u$`;h$ zwEzi|8ijfLw-&IoMA`$fTq74k5Y294s@3-x;$|-d z5XvQK;q@`MyN2Ik)Lgc5LtL1|oQcs<`sBqjpug7fgH~6zH3|P!K0TYYQJZ1Bq-muw_9#82LQucmIcjkc za+y|XBtMTWz!piQmc@ly7LMP^W@`xii~eUGtbYWp*E_?u_b&IDy5-tG0^0xn?=b;G zE$}=X(SiJ0W^L<)U9d_6&RT~=!slJRoDKT+`4OAQjAMX`C8#gBq=?;s-1OE^3U*g0zTJMeGIvD+J=Uh1+{H`kG389 z{%_&!o=Wx7^Skr1Z{OXv4Opwgq(Z+K93KY0K|=ja?LL z&XTEdujCoCs!u4D%L~^q(f)OLVWuWl)sXDL@6YsQy&TnVzATtKOF!pkluTqrwYc2f z1rey~pI~&BR^~1-F)q@PJlCHU3Y}53?9yF0H++}~s#`*$cx$J&*Lc!eD)G>OG*(H5 z&QC)82Dm3O-^;5@ste-9K^8t~)CGb@y{?CPs2OcR6S`Du3#+$fgjz`s}Ir`6X@XmGD|h*AV%nB5*9JstK`vHfWRi7E`8J z{yKB4moof%l3!;F7&3ZbnVJLJcGNr`NO+8H0~3VQ@W3q*3PJ+t zDUOcsOI&kvslcmfJzxU@wwX z?iBVW{lXe|g5cOb_TU|ASkq%x_ayW%(vZx&wxRv2?sPv7FTAmBRdVy6AjbG_vc#&@{_;r;JYJGl)E%E6DkRm`D*%*s z!ukrB<@TqZ#3Em&y)Ggh=unz=1!8>vXX*lUE)tZU%wJ_(_86$2VQV7s6ix0ltSDBW zopLkI;2Fdz60iQxcf98p@zQ1d(tTLSrxW&aKd``H-wa~>pQxCdx z{{wIBtG?hZTEYDny!GxO6fjiw9wsy(g2^(Gtj!Kdo(M;*DH3zLyT;$uG_2~c3TOS! zWm}i<56d1R{wT$mcin-#j~!pgV)JcF*DuyFV!XM4H_n zzRVz#p<-CXlQErE59IVP3aw2*VP7!{=jDs6y-W*_M5HT(q|jNrmSU@RA%s;UC1K1- zX_U)sUp*Eluc+)jLgV&;XU8~weA+5_71Nl}obei4N(Ae%p}@WFPHVPlyV4CR3E4)%*+-KWu98buulid^ngwqwA*MW9RLv9Uq=<(+WjF)ld$uAk{$|3! zWE9M$UHWD1eVqOWg!zBwBNAPvKeYSzzehep zu@JZbWBqS#Ncp*+pf(Jwx$@rR!<380I23%8y}$PAW>{8o`@)s}^j^W3R-ac!z$W*1 z73}67x48XUSHg$K#E1afDR;cJ?r{(XO7K#-S{BU}UGk#JJ4t>)8_4dLdH55cb=<>@ zFg~nEq=?AO%TKs`^BtH}l~atznjPS3APcOXumAf5xJf&)yaprt7Ifs4&Id`&4P3UhQuN5#1loxX*ZrJ7w2!3ck4Zd$gXAOGbV~q z71hu!ES?x2=(Rx|F?s?vXGW9E%gdQwXMf!pFR+l*x&sN-Ojb(@UPpz?bx*2) zT-|{=&5fgwmq1~0{hSsv@=L!{MCf={Q^||{IW3DL8V*J|zCmytVTTuI1?ADj8Z57* zmAX!BblmP>-95H;vx8Gr4R^(NZlf?$2dI68Rszf`Nq*F%H`(Z|^=_#f4iHyi<@*b z!>KRjY(*mf6Nfy(m&UgKP*XfKIIP1 z`-gL0>`8q;Y?J1WGV0z9^^a6SY|petC-GE}{stqzWA)}Q#DDjUA>=VAcQR+e{=85K zggp5}-EcKG;+rAIN7mP_&zE%uOF}-XlGp4^P!g1}*f_R0rRP0C zgf@LVZokb6=MgAu@#H$mjRVf85UEM&;`9*GVp9O^O~IAvxmxwv2NNQvXZhg)-Jl*)rCfcoN5SvUTA*-C2H2%Q}Ip6|dR8k<4$ z;G`Fw&8N70st-HkjfNe7A+qzD1I27}QkggjpB?-=Yqw4#P{Wg(e|!`ECPNDE^pQk< z0FJN2gEoBw3_j|z!bCB1t%Vp><_uyiEm4x^=W((pPxf*<+1R-9?l^II)0&P6WQ1b2 zX8oPi5sO*gHtD@o%tUf0M0N?RZ{(fV|0WAn!_RHtFOM?Ccq=%uX)$Ch=@6_&9N{Ws`nrDE$B>`%05>KJFU zUg8_O5ut^Dd#6`P*xBA)>Ff)_~94f$ac$|64Qb3sN-yE zvw-(tw1zm<7_l!V3X)s1{yVev>M+-lef;$@Zcmz-lKaUF>ZpMzgCW_3e<(Mcu!w8V zE?(CGYyWt4k&MYOs#p>jxKXmM1?C>*hUwqy9u{es8lMo zf^#DN&=mbgD5lEJT)96d|9tOwDe#wYO~|)Etg1_~9!nS-U!>Ac!?5G%#wYlN2!{kK z_kYrkZ!Tv9`Rh9RZrg35KCSnXkAsW0ejk6u9*S872j8p;9*$^K3w#TfaaY{usw4s{ zr(Sjwz47)PVz`81p>U z8-_G870xM!^IhIxo<=R%pk$^5^67CMiP*8I_4KBkv7twng!orxDe${!>Tn7p$LW6v zpsRhU1&$odxq%w)D0QtugV$G2T;3fD)p$)KXZ0lW$!L4rN3fSFqv!8IZ(|##xbPM- zdKbQMKB8+Mh;TZ2_JA{A@n?wqYhQmr`2k%&VQd!{%vd67($*j#~99Q@Y6xET{S&+1Misg0uHVWz6pbmgLf$!nsk}FvJT$yKaFFLaE}Mb9&h(O z_+0#?y&I8DU{5T=>*vyyBkuThqJiBvJHSZN*@PJCy%jHOZQBCQdKvt zY$%MzTi-y8q@(+Xs+xLJ>;*zE`#>&*V{=I^c!>Y(jvAZ}&ojyDhN#>iwRT=oyL)f=-iRw^RT+%agvFZ{>ID=j z^s2LXw{HA)OLOg`@qOvIkL4-st9*@JcTSfY!TWCHv}n83weD7+?Hf;n(Zum!2 z%ClEK9w$e>yZF*1CT&J3+!;Ul*}-<1FBA3hb}IhOmhbrf5_U46)A9lHG&uc%YkWnF z+y%^8Jy+KpGA0s7SHniygKUoGh;W?mE+qjhD z>P6@3A0juIFvaw39^mrcY?#cMczk$La)Ha>0#8@WOq#_8Pj%V;&pb+>Kf}HwRZ7cC z+L}2!ga^QSj(-~c4h7R>d2sF=NSjL6)1n9ACupKy@VAD2xXR{o+odtblPFQU<*OPf z13Zb|fBXnM8KLSz{avY~#__6#>@5+ELn(3ymzTtxNO$#}DzhWT z7JT#%|Rh=Zs7_f`YS0a8~<&vK@n4Mp+wW5Ae<;H^h5g?(0|v*=`pU&YR+n zka@QI6@A_?Xx!+hG0T2MlCLV(q*s&c)}Vy4#x#ecKax@UdlW1)-(AOgnnp0@zpY7y zB5h}a96$z_bp*I7{8HM`GW_tPYW7eo+AARiKzsf9)LYQlRo9S7(Y`z`Jl5|U2GM+9 zDF0fNdVFAf#(xxfVY z+5+1L*p6BY+NS$y;8H9P2~EvabFH1V3kx9%G&Xna9&&HrG^v{PkP1b`mA0Ay7PB;S z{oYgb(k$p)))~$=0{SWxaiY?4Z_1xZ2bnYnB ziwK0Y8OE8v9GR*C-gt2i68Mcp(+I8iczgY?qa-_MZ^7^J?VBFpnA&^bk~tj{>}Gq{ zI8G?SJJrFw{%aFr%kQ;2je|D%qV}3#@=-}WFkp=BAgR>Tl1u2Wee;xtOQ!FoU&8A- zoc_n3HdK8cJP&!Y_4FU#v2V>O>KR&NnuD$r4KTU^-ic%J!ry#y>!TZa6YXkzM}rJ1EvH^*-rU;UOMmmSYfXZRfZFK{!C5)0LY0s*QE zIbx`7zuFyWbFE6se;Kh`P45#?0kCDcWormT2`r79DIe=~J|?z$?u`e+PP_U$ohsml z(zj686Qa(%x-SG+Bh}-vty7N51hNh!H%q7BvS9TXbv}sTnAk4?SG+0B`3ZGD#Y6T7 zi>|IOWW87|0#Qkto=FujHu1r|IhDOWO6d?+C%OzUe+0d}nz;~it*_JPxE23UF#wF~ z>7`~+*zMKiqZ~;qYbu5(|LHfJBPt;uyZ&}|CvhU3zYEa#NGk4kH;Y{RSA^Q*nYdHk zBn>kpCW+tZM@ng&4THOZBg^{KfhgUCo+Qf+go|>Lw|yd6-$L_LYL-$*4L#56b7=oK zPidT%QPB5$MZ6DY_&GdjOr{TBOisW6@d&Eu+aEGKRj99x+T#Tx{Ln$l1{L-cNMhvX zj^g%{kIN_YxCbN)*oIWWPGf;2E>j4Ri-&fqI|4Tj!+kMUAxzGC5#nM3&Bd2&BhN`q zPKSgnh^tnM4xHUXh>5*+JID@Ad?MQmAH^MLfqySPd8S1A8a zo4XYZ#$9QJRmVQ@!-z}ciE_&E-p&iM^jkkE9piQR3TKw?c~*TfS_wN6O3CkfX~`3= zRkNs%a=SDicYU$@>eA?*lS+jeyr{mPV}nR{=KS6i98q+|S!5h4yp+kyvim`wg*9~| z2x`MqaabINT`fBtNvi^}sPZE>G&u?d)J^c}-GxPDwL;R!qfZ_p3!i@+mWZkii$*1Y z4k8|)e_V)z6YEzQi`G^jpq?LUS_9-34ko#FyXUR4j6&fK|m?8(4d zjN4_K*!Ez|6ok)pq|-L$$Q)wn7{KVc)j|+uZ7pvE$$|h9Nn;Ig;QjsQ%bDSG)`BO z@;BMl@TkO3x_eUR9d;q~S)U942aQo*HwitGuS}E`i(ee&m2z3VM9Q*C%Iw8hCI56g zG5g*9h_+36e>3~eF?vfpn}see<<<7hCGiNk$C~oyLnS0&QorzVpbstkIlJy*wk$6c zst#Il%bL`O)njPSnqyF7N4gHrK>ppvn@obd;DmcUa&pXqR^$L?iBGVFR-<}JAqQ&t znPZys#bO7<`<;V{+Y&cT{olEyy3I8|Zy_Z%H`Ca@h1(TT&|!QaicO_ZD@_V~&+m_& z>I`CJX*#i6X=2w?Z<$ajNkYI(aodbAX~j;cP@HXC*agnOfb@CF0%vGLONX_0LK-Sw znJ1qx9V|`R!-P9HS3s+Heg{uDRgN&E@n^>YXq#KLtF?ZB>dZPX_YpUqQDKFgOkQV! zvEIuF6{23`*R>4_bt4shM#X19vo2m;P`2$m{-N6s&#$Nzqc&xlVzlt!*@n9_DGBG# zHF70nBz!RzFdtf3A~?*|a6FyspAa3^nTcPd4^`nOHp3bNPn8@Qc2=)7DWtptWdaf_ z;9*u#-9qjChCW~pL(vv5+A}9cYxUJfW zF|W?zd!fhvt-7iNL;fDDApNJ*!o8n&XD;S4tz}xsW*_trNATckx&l^%mR#0!YHm+& zx}_GMc7N?vg-M(gNW2!9K_C)xgv4k3{6K?BUD>u zLnfR_N?z_xV=uTLbWB-O{JfmamqYo|Hzu` zzFpg{Ou|sVSR?g`j^GoJn6I9Zl=w9rD<62^5pBqw2iq#bHhcs+Bi4hoMOi+37X2As z`u3Q^N`W^uvrN05xh~CR^hO@yKVUZ2&3Ydy_0i?*pMcSy_#?~T*?tbPpbu=L5NakOGuL&!3Ya6i0 z+O$z0S=*jNSfHA-$di-h;|(`+FQ_{9On#g#PDNKUz~fd{Pa+=FO%R-)x3B| zG(%_L^I)}hYFUfxsF2>QUO0N66No0gj+!MU?B==Z?R)%UNQh*nzaA?ShvHznE#0n2 zBCsX4IS$cO0BL~B!%Se`ojs4%+u1YA#oo5)iz#`2|6)oAI^G3b!WavhmGfEGI3)Uk z)53D#?X{eROP&@%;zUG7ugTR-yZ?JKVCv#=*e_4vh!!x`U|D;3^VdkrMI(g?F^;k1AI-q>5XT3%Mw^q> zjQ@HUP3v4M<C3O^Iv;Stm45X7;$ z2OV}CF8E7*$RrqSi_hKInK?3k#1V@j1|!Qlq)QCB@hJk6Yz&98<`R_jdNTX zIg@&iUm?s>p*|u&%m<>GIC>r$DHV~^LN95mk8X`W*v&7vC{ik6ndzJ`#B2TQ^PP=- zeuFv_%VqW1rmY`&-yVWka86ZR0;{Bd0->)1% zyk+(yCJL73+l|u)DEwjvGrpEk8K=HKc{y|smdzTUo~q_p*)AW|+qryt$mWiPto3x1 zdQX02A1gMzKJASJ$!D0X^C838}bM#=T4jKv{V-q z>Qpo$K_gkDg)Ki6n5p75l36bwL_Y@{Pb~w3jTqSq+QH!*#*q^@gN?B4hOj%<2hcQ) z(t-&+=`)irk{ByPkJ)zO3u3Dnw#tl+Ko1H#!`!GqZ(0GnRNU&4_7bAdDgDe(a+ zi;2wTlWnAR@nJW#o7Q(8JzUtAKoe$3li5<_V0Dd{xs^ zqD>;yY@4E-v_g?VsqE*9=#3$6M*Xyhoajck8O}%u8K-M()~JH}hQQbEA zFVn6~5T5)2ThLE5v*VcZzWI8AHIfXQ!J&Sx&S7<77K`6h@Gm`*P<@Qp<06)ap;&3~ zOzE-TB>86Pmt~;R$%Zs_+n}2inSSBGH;Vw?hL>g8S6^&tt-rZ~D4%>7V^_6{`0e>Mv`{I*eaj|Y zKkMUk&dS&7{I4i|y|;oZ9_pdH9)5FU4FAxKO7}G*cRU#sFW~0cb1Dkf<2D=7Su$_F z6BB*P!z*$)<#&za+u!MjOYv?1zg-Eh_jUHdJ4ZzK_r4;qt*;453{W|`|wt`JNohBY5N^734;KK05x9M z^6Bk?KHHsv^aUT<%fH= zViTS#}-3M0EiF z|F`ChfII+r;L4fDufB@x4|AQj_@v!KOZmS38bv1bttCHLW5Upswl2t-yq;KnIpn>V z$r~2RVKJTqf1;5@e^+Ap{tkDX2BJufs5HVJ?a4|xmv86gy^ISgR&gg$a z=75G?RJsRg(Izd@NtoWR0dYg*x#3&JlhHR$8_hU}zpj)*PZ2QfY2`ot(uXZ`gp7+E z&2>a_s&S#2O7d|`$>CE6v=rlWJqlo*qG7nwk`zz<*9U4+SD~O)KzbL8?bqn+$M1v`3UxM$qlBCr@ zCF_huY!LF}%O__-ZB@2vT9T56h}HCIMJA@?3noAB+KV@4#o6)=#MCn5yz5>-SBqb{ z(Xp0K#QQ;T*Ye3Yot(1Y+@Abz{UAveAi8$&ZzVRni-3jjO}~WwnxA>YO14~#Gw9t4 zuW3)0%yT1-WC>TDd2u?O!Ho?)&N&F0H&q$@n`Y-P(pdJ4BU5F^+l^%9b+>+mXq7+an*gM|uU9&&=0Yd>a(75w-GpSyC-bOm!E z%EQYa-0`)#`jXXo%QZCE{ZAFeFmk-PL}L&ooAGJOq#L&0D~$biziV7a2JphGMKY|c$#0h!x`j0VnUWntc8 zi-V{Hj5V+IbwGfSB~j)D8Us%E0_2Q1FS#U1a2I9v{PZJ1vp!cmOx;*1c}PXShNoBl zWUiho!lDv=UzGj~LPfw$^tp=PXU#=hL@vNY;8;2T4&^Hs0P&pq7|H{A<%(Bil)+nN zu$fyB-2hMdxAzw2&_?odMBrZw1+ZQ$G+%ovfy*MzChr$0T`&eGVn%mev6~99=7RY0}5KsA?=S18*}x}ruiCkzIl-Qx^&mE3O) zr%U#kAoGdwZu}P-lt^B=%}Y)aWSSeZ>8ur9PZatQS0M)G14J`T_zbu4I}@8*9#!%q z>RDq|2aB1(1UTt{kby}>>H`D{kSZG*ap+szzZx9%t4f2c5Lht;(t>+m3=e;+SWhYe zBr1VUiVT0Z=(dP%wAk#S0n9+E^o`L1yKi@385F7wzB7TsYh?hg+&puAx93Y!smBcb z$30&=JUJEBN+5jloqHe*`WEYrmZ3eg-_($`lst8EZ}c>@T}1}@(n~IzIU|q_G_9aO zWFQ zf;V8w+8*+V>GGosysyjlnYNXjI7K2*)Tui$AUzgZHS%kI-qk>}t5|wBdHjq4iX>PH z;}H;Se#JlHZYi(rncT!95ZfOU)bq?tH^19=0ENM#{uyt4`}igUsQ`)1v1ZSCina%d zk9|`9!RTI*e{^A>*Cnn5=HoT;47F^o&3++1s)B{jkeL>Zj!XkcDUidGS_*FmJ#wCH z?RdbR9BIRPYF_A~>a+T6zznJ*YyEVHff`I*jG(Y2{M5Dx5w2_qgA49bi8BmmhK3Qp=;Ly3r$xA^z$+W?~5| z$9OlDZiN%MmQVqdc%Yy89`0hptFf#@-YO(|f24#_d z5@GMON68PcM~o&j>-63u-HJ-}jUALJs#9^=Dxx({SEyav+vtXZ(?QVD(9-UCEDlp9 z2ni^Hi47oSLGRWnnZq5I2rB?Aoi?>)C>e0;mjet)ws{z%DO|JpbDLnyqaNcf?C?y9 zMm-R$J%rxekm*y^W%%60S*#2vm04m501+iTsW1Jdb${})c z=HaXW+ryl;n0cIQP9*uD!f~JFc-<|2(2%YG*n?lXm>*saD9+)`8;DPeGZni?urId4$o2ndK)axPHOb;r(fto7f^%C6p1kUT*`pJ-UmVEe2p7 zTqtu@4=I%c1iEs(#C8p9krn(%MEolZ09X;>{=i|?nK zF?J=J4h+g0>uUYfA>=1Jq%G40%ef#;cdkk_$pM}rV-4G*>C=4RxsOWtHOyOXk^Uo& zocKGeN3>>_wVS{WNd+mYd%ftTu6hmvoNvTqvDqbrfRM$1yUn)BP<%LL&w9ETD0jdx z%!<`&_@*Echt_R{$bH&bg8&|UIZ?%>E|7lA3VhHeIp_SSq#;anIIwvXcYc3@0D|qX z45%%A)GVzSwJ7LTXU+MNV06Y)r?8LqZgIsbU{ZaP0JV#0aCAjKqyh3mU~(aa+a{-f zfE$WVzMTOKdf-6_i$Gmze2irp`j+QSugzZ?o)Yy^0EdAoKIvHZADF)Y?g7hAArh#c z{)(szC}5D+r0A(zglqW?5;aKM2$_6ZY3P6`lH(LF3>DQy8f>SPdkZDM-TqDRky11P)dA2IHoBhiqV@mQ z$l3ohod9tByUo~!TIMOtJWbdu?JAGWL*y}R=3yCX9(q6z9y*W3#?Fac=Qx#!;X;ZX zO*G4hJe(9Iv)l~hF2aZ?j??{iuh;!>zrSCfKj8Cvz26?t9dQ-BxzF@q0j%N4u8kO7 zDWw(WWQg48?%UvY8u|q6&dcQ=`y-~z5L$h7lLztsXhhKSe*j1!2X;+_I;4k}AzpcG zYQ4dF9hW105x|!Zi8Az1mNWgjEt?4gN^2SwbzyY^T#+(OE@`5=x_qzc8AWR-lE(k_=ui@*wZccF~4ESsrGY`t-RxBw9*W8O+tgb2>Laa}1$IZYPl`qR^99 zvsL&4xhVTpr6vwNXYV7k>wY6OL& zAWn#KYys57i`k4@PAhQ3n)cxtoWtTN|r( zl;9%*_W-XLk%7Zf%8KD@;}`q{)iao=J*MjGAdM@wT<* zZ%Yie%iTeGd5TcA-u!73dy^OL$uhMW^X$Oc5JCAcDY~j2KH~n+oZ%E;*JLwbgP@(y zG_Z|D3U=R0@Hvz@)^TYNBRfE6Ys|(Ngr~UGopKhVhw7bc!A$&_bKYjT7s)`_{zyym zRpWExL_eUf_&Y-9G1lYP@~&`;##;}Nd!}YHii%!zG}dUa6K@ahnDbh)^T*?0kA7&o z0tF^QV?nGBJBHZ`VrbG&WS_IN7#@fu6S-loFzk1`5=Q65RZpx1PL{NFtj*7;EcgO*L2OA9 ztI`quJY-o#M`^CKh}?DuLLN-%`3ZlsK*-%{K5;qtU0ko?^FrREGjFFWMX@u@RCut} z8trph^6=+n;fnr#O7cQNydlp&b-WqkxLu3hH`nEvZtyPEKE<*#G3^bsI>JP5O8diD z=`T^E(yeNF>G`U4l&iJE?SR5oyIC;do$;1T|D&v=JE4+xHdlJCbRA_A(kx?;uj8(* zz?HudpN$zrjFO#$jgkNGLflhgjkk-2r@02j)IL3+CkPS^HR_Qx<3*kGE-vnrmtD0G zugPA~($xm_qYuD%iiz@Ku6g=CZuc5X$oRAK{Ut%-1@<=t!I4zJ?D1VMi))jl8)Dv| zvy`^DZkxCArirmuS$jk}8SO|I*KoONls$mrS&0DRYOWo=_-)Nb0Xjb=t`(#`tJwy?^CKL`Nh}*if=e;~Q1BE+oEb~> z^-IPa*xjN|ynMZsc2t#t*7jj<#)<#(RugZfE@3Px#32;bRa{vGqB>(^xB>_oNB=7(L0{2i%R7EdLcrHwM z{{Q~|{{1gbcr8wNElznaOnEO(dH(+YE=+m;{r>s~1{V7e6Z;V`PIxd*c`!|Q{{Q{- z_4WV%|Ns5{{r>(iO?eah4=_)7`v(U9{{JsdcQ8+R|Nj0iOn3hO|Mm9v`UnR9{r>*` z{r~^|`~LqhO?UtO|1C~;E>C#>{{8j#_4)t*6Z#T4P;(Xh5Hn42QfiGbO>{C%b@l)M zFHU+cPkA;|d;b3a`~Uyd-{?nRh%ZciKU{*Fs=?sr@iI(#qOr=!&)9{Puv~SQ&C%KP z`Tot;;Z0g_Nm+CA{r}C|>-qoqik`mv|NNAry35z=|M3y` z73%Bk{`~v&1O?mv+v@!4`TYDbOn3GE_0QDT^7i^TOmnur%j5jxd4`;0a*6%(^2o}| z`|ImL{6lYmm@rRwe2AWnp0tXcv>Wsz8~YXS1qS)z;yhM<*yHl+_Wk7R^EFX=keaH5 z{Dm|7GI{)Z5_!!gtPp#`*3j~@+#=> z_W3LYyE8H@cfyhv-w$CSZ|V8{93QQ)9?H5vbe-hW{9S)y;kd2 z`pe7sLPGnjtjhAs`qtRY`gf;O!z8xZ} z{i~q-qQm{etn04Q^wj;Co80u>yzach@xwyxN6jcMNLziD`21_K zK-Agez|Q0W0s-6H+;)qp(usH z@YvXP=y|fUvY0SQV{L+gkf)li$=IEp#bswVK{t9mU07IH<0mME?}+A>mV`}g7+X|L zmVTO>nkG_et#ycCnviSXjo-@Dcc7)ppsc9cxvN=Xx#-_DZCWW>?y?f-L5O9~;{pVzr|`_Fa_HAee&uz#Dq(f&Jy(C5}d z>YYEfZ;P#E`w;uCHitA#Ere2ATUyDF_CEUnTu^QH=S$dveU82Tx!Ska+KPR~Vz00_ z;41C6bL&0yQo`C=wF|1ap()i+N_|WLZWLcuCm%!+wFwQWwNg`RAMT)BiuV)7#iNy?d7$trPg9sa5XqO?v~KD zi@|ykv=czEiwe(nf5{M-)B2^*R)e+y+LwgZUSpRcXu}DuJw*KY7TQ|o5DeO8&{l_b zYW8q4U<9Of*@9tguXt|Nes&SGApzxJFRg&#r9CuT3HCK9<6nDJcrMidZEdqRbb})D zs`2k+U*2#n)jllhVKzf+YWU=o9u1;WO3Q7Yr?lDs+0Ex-Z<%mky1f(@ep#~nwM&b* zE?jfVSd0QM+oK6#D+WFuk$vo5x%PtHcV6&XdvW&16v6|ZT*8yIHIA>aFD*H532VmQ z7x9$Zgr{ZqYWUk#=MC$3ns8P4MYI3ulYNFE((PBo02n?u{A2H*Z5;*t(e{?D5?cXy z0D;Sg&!*V|Y002%*e-t5el}#oYqhlqv#Irl8^C5t_yNoler|gXThnZVEmYobe1JjMl22D&!WLla>=O4K zH-Kw^HHQtzFse9WY|mcwK=*v!0rvBz#lbtUpI$Bj)(rd7cC0P?)*k%^vfsg!nr(BQ z6f-tkF9G|eadDK$N3Z2p@GM~16YUijM}UDzi@hsxA=>sXd3wX*;ELwrumw8V_Rh3E zcIg)YQnfg20obG36D$Ot0jx3c!$}DwUxC)X-=QrThD*>+S{%6%T7T+-7E8Anw2xSn z_MLXk1vUUSP0J$Yst0;P+X$_F#G`K$TPSC1TBL%zzKvp^zc1UgTBFw$2vwfj0trEELxsf`Isco5V{s)d1{1{ud z^uD=anqUa*rp!>{ey_4KIQ~kIS=ewuxEr$5(mdfmt6k#-*l}?fwD}%d98hri>OHgx z9t0MUpluE<_nM$JoaQ!`H7*z9wRU*;h`$)|{I{`z0G@XKKd&t@VLBidM`V0i81NtL$?p z`x?HZ&P^~bI2Y|rI2kjR-crkBlG7m2b8!Ep;fCQ7R$K-=33vlj)0VgEx?&?YeS4Da zZcjV~V8CsI$~A_uq^sFzlX0o$@05&dw108SX0^@6OgL$G`?H-)Skj9QbZ&e*jre#n zH$%G69*uL>+=S5E0qp{R)oyU%9<>WNpp9>U7T7*w?ciHaPC(SlPbrV=Gbog*a2CQ1TUtCUFKB4!P+)3sm*NN)~ zIFHB5LzgB6cYu{xc>}nxk|P&~?bb|Z+e}8ze)kq9V2hbYYDQER#@<%A3+iyNd=9OCOpk;%Jk;b{7T2bemRHf}JgxRe^ZapQ>o;-+U_c3#Jucf~_Io76%nDb#gQq}W0|B9# z%Efk)?!aE(aR+vT3tlSk4<{x%Xmj`Gopq*<3wD5H7!wuRtpxp+v2DtW}Lt9~==mHSh+TDoQS4SMZ@gCYui{lXB(NP-0+=eZd0sDZ> zka64Q+uAwiXCl6-(2Q}r;Z)!9)mD?a4GL))_1Sgy4NkK;d~1R=yN4DQ%#J=e;1g|k zdSRi*W?ynb%Uy86bH&{c11@hJk-ea8b|>*3TE=Df&^AE3ASe*D3!$||jVux(cS73| zyr!8e9JezIT6Y<8#&T(o@}lXgVCB;_iC44Nsd(^wxy(h@bMi%jbFDPmBAjSd9w!!U zdmaaZ;zDetg`3n?Pog!)na+~}i-Q3XPr=&e3*jhbXZ8Zglz>BVhfhwgQw~FwDV!Kr z;Fb%N$w03*&8!qPU0`H7HhZxv)JdP5(>WJOp zkz}Kf&#&vU#};ACBR>Qm$vzrq1`HLU#R|#hS%wjdBiO|fyW(34Y|%<+weagbv`x?= z_@j?WXz2poKx^lvRuzAH4{ai}$)UBNg~3ZJFx@aHf;Jhnc^?TYLR*kzf|tRNF`Ivm z$jt*@ICAzNaX*FUcUmsYpvmK)nXm{gkHrCNt($_=*4ne55OjYFqG~0`nCy`+k`*8a z1qoSJA;|(^Q^4b8icqE>>zk$_>e#oBVJgyKu5we4V=#jFR;HG{Sy z!)_r}ME(j!*|yBe)E;2~8VD9D_8P3B_8HvEJQ3rJySdoQR%N~5esJ;e%5u4wBM|0U z!D5Wh01W|&#Yz!-#U2JXWW(pcV%R|eD}Wssc82r;ue7BbUn;3r?YYgo3dYvcqJ6>C zG%`3kff>(rMr;>mrEIa;y5YWuQ-KGJTo8P!iX26Xvd!zNt2Yb0nvZMCD#rzNiD80h z#4W4bVyCe}PA-S4-DCHNZ-0b8Rp}t?<`jH6w5cMfM~YFdCZXjDEBGTyTqm^2p=AhK zswK^l3h)w@)kFksxY)*`iMO-(gtj4uJ)mugnJByx&~6A6xKI!+e;g0HZoRasGf{KEXR;n zwu$*QrUd{{7)}HqIWFDS1RXA%Q$bZUTQ~V3!uzP*gT9p*Z?fGIo9ne-n3v*xZp-m2L6tuGM4lOKh(V44yfPyqP(e^+M zkptR9-zOi?X0!6kGJD<#7o}L;Pas)lKW|e#?qDnqW)KtnlDj*|@~`pJrl8ceIb8G@ zc{jMC%4<9p2jE(QQomd$i}KF61Dsvw;z-Bhus{ycz9Mt({~bw27B|`m;k$x%)ozs# zNB-+v97^PSVhN64)1icWD@~cI$kb}p;xMa(ROXsmIv2-88`c#3`r^1=4O(Pg>i#;k zlSe=J^_v!llEf#p;e?j?S}qQT=dVDUcvKKt?C6erC$y=#SGRZb-LJ_ciMx36of@g_TD{ z#4-Bniwb*KX2<1jnQL%8>gm&f7RB=c?IO#n@WejL&Im$_t!#CE1fF&<-a{J%Eec|) zO}-J@`h?KGBjMbVplz!e(@SJl5s}axw3$!J!=6-E9`OcktIXHh!GOZFt*|vcKGGL6 zL$cUnumyHOv46&*W1Oh03@c68Xjf!=E~w5WL~3?)*w5ghPFw+*k(D`nNTfxE5Je~K zWmc}K@momWnCY6Sati`S`Q>HE?Z^5=5=$ z!VtqiLj(h86N)q4KnIItL3(BpTjs)yLaQt@@h}IpmQgB}I}9%XEv%4Tm!J(O;c%bA z9a7LbBijYPoQZL6pk)qRu!5Er)}c*;Hkrqs1Z}y2mf3lpDoFKk6QZb)vw3;^9qQwS z?iX@JUL90;#^aLdCS-cV*9l6-cu}F!3RE#M5|d~2e8hR^9{hPl8~@W4d?r<{yxbAGJ#qYQTM|w5U3Xq(dO25pmD z!;4q-0S{hl2Z5U|HzTLbvk2Ex?3_!?DP_>hWASc+ECA5`s1uw9j-|OAMoo zfW65uq#+|Qvr4MPkyV+Qjw(O#EKY}-cn6g^+8h;!RcQ{#;;@^?QV7e;v)K+D`#}CgU*?M= z``W-`NySsPel6Njdi;jm%miIwsb*xDR25&(#erP_LJvFwxG{Eqa&dH+^U`^PbjC=1 zL2K0-B+`Cv_{~w z@lHF6Plz0ilE%t$M4G|8&%%5lFLTk}s86<7S9l&~{LCCNJJ);AFX480mI;IlMtKp( z{?)9cEjgyS8{)DRG@sqh4P3y=!>S>5ojk^5nLyrTt*Xcsx!ADV+q%w{wYl0MWG9)O z*pc-tJ1SPx=upSlExlgg=Ze5#i^O&gC<%?%IPm~C%+d}|usRD%LF&XJXGN|UM-&3e zduX{v4cg@%TFaq4WQW$+Zal?LXz7~5NrqP^Xd}5Hi`$(i3$Y1p4UhJpyzgHE?K+^< z%9>HZzkwD>US;E$N@v2c_v-Y|h=UnyHM4qfxi0v4?B&bllDT9iJMSa0-9{UI^LidZcQ@{>}_483Ajxihm=muZ_+`qd}8&9y`PWx@e2e8CRI z&6X|#2m&D1m+b^^{gEbeQteUYhly_3%aq6Yg<-lgRc%A(g+Q6ifU1vX_<)X#E2ed4A%@@m8)C1alKpQjD zoPrjQ6rm7HIObvBKwAWDxq&u0wArDBS8)Svx`%cXw6@TZ5oDCpaq%PudrZ}f3cPiM z^E#g^*Q#>YVXVf3y+mBH9Dq0sUSys)H80wz1YXC{8&qlZg%U;hX-Z$Hi0;{NCri{b zy`Z-S>L6OSx`7Dp{QzL1<^;i(=D zo+@jIp9?c{+*z56H*-y^@K#jOcyd|F<8>#czNA)+TOky?lToMf>RE zcmDF>pMLV&x8Ie6Px6V5kf6mu*D#XTm*kKSax0AsSPG=Wpyqc2?Um3n`*1>g?7QlD zz5f#02HtUMO7q=A%X8;|mOxY%7D(!lmm_G~2`!@(6g5b9@NW~eh$8v!ic}A4x3FQI z9H%sR2}YKHokzmVg3qX5d0Cvh1DiC6HW%P}fbk#-0GW>rP+|1(S6bMNWVprIs9QW( zYTx+@Gl{1>7t3_k(6BL{5psg3+9vofNehB`U*(EBuWMZ&Emi~z0$;T!)vj&zmkp)y zPQsWu>R-?sQ zWHa*aei9}frAO3bPkRNwoe?hUs#g!t1??jaAwe5YXu$wmC-T4nEi6=YXwyBkh6Z*v zp>3N}0IEp$f;Qu?6`9fl+Fn7AMh@S8C1~Yx6d>#y9tQ6j+^O^`v_Ve%uG5r$x*KN!o!na_#DV8fEB1K3ZJN-9elNrfoUNn$*VSX8OZ`~h>G zMeeRjFGSYK=v)SwVffC5L1q$1X-k$`FG%2=T#=-d49!0_1X&|sTEJ@r)8w!J{I{R~ z?iWA$!C$`nr%&Ji#ebTKzL;IIajd!}U=Tf7#r#DKVte4$&P;k>Pf0nl?I*M{P5~@79oI*2bNq!rvHL#12Z@gqBUuuv4Wo%82I9-&MxwVl5OXY zzw!R}|M6dbj3x2eci#W+U;M}0+x+o6@BG`xU)j>f@BHzHfAgdN{O%_|`zQJwyL}Lj zr>jyZF{>qogk&hnG@_HOvEsj^AjcG2&jzXkYM!2F>QUbfg3Kz_V1X;JhNLO8XnV*^VwZ!XW zRFsL8qA711w(Nw*VhQ#|glbj`c^X*8Glhq0<$9DLs@PFcnQv7?9}tuSl;UX=q+OYG zTDYrc`)>j75_|I@A>lMJwMdWbiWO^XZ8fq5;%a;8RqZE8D>Gq?rj5y?MjWYDT;zd? zR!#0NW3ayS-X}l%)qlSIl^5aq^4EX-*5CZ#$8Uf3+YkToi+_Im?H6Bt=YPNVFF*Y~ z7spqwEEFOq9$v0#YnC*yymdph7_Ku?=4f5q&Ex9G(!)pEY?-b|7$hwxLEG5uazY#S zHTA0%K8z_TXjz-7Aidu~%RmktBZAh71`H(RgCEdx-#rN0R6LCWcT&(Ug4Wzp^Cx+- zSSsa!mPX=Ae&K+&4m68V~ZYHycN!V4MBNZp1c!9XWHq`Siw5W(F z!+8U3^7`WeZ348sOhIeT4Ni}MFQ%i#tn%OsXQgJy{Ufy1>u6-NGj_Rwwz6V;2dxrJ zkBKneLdyt-;WeyIh?@!yGmr8hdRL=&)RG%#B~C_}lnHWkku!-+@Hxq#1u>$~)TnVM zF)Ct=+0t+tbO#Cp*^wZITC20T^XW)^Wu@H6(pWqOoEW-BoZ4CaS4_&%SJkEYH8Qo^ zN?gy5gQ_sQqK`n$J&`scrWpNnI9`s||@lNJYj4)i=WW_u5J zkFH!{_Ad|n>?($rc>ibdj+vzBmT7=?>bO zya;nb+kA19%n~!5n%VO{`G7Vb(E8#C4lTQY?Gml?1}p4=sXT2#MrG>kxi%b9bbwVS z(ni3dDr~WX552=Ec?x~@32X2$6mK9sYfM66D+sjD$}6>8BRi%P|E5&vw` z&9c!fupbDHSOXP`q-ACWA60=SCeca#Kn8{w_V=lR3%ex6lSa`$%ZXB(?%Q^3d}Qw2Z3mptV}7yt(RpN<^gCcizelZfXU`ir5;+oFNEWuJ47*>}sS;Co5L=tzDR?kd<63yfL;xB7wj| z%s7%Lioog?_GZ@3{Dg(rqAwwyv($eERRP_X=DgLH@)%22DFkV6KfPeH7T<6*q8BEm z*)#C?XxxU0%!7@ISC&SC$iUbUTZI3qyf~>+I7pObM9bl&F}Kpx^?_2ww14AIpZqP{ z&EBtC9DjK0D_{Ni_aA?@UD2OuOa)&Y*kK*nr3hY!49~*@_@U@#hQnqa9@?PLUtt^Y zvB)MPsuHx}O0uCvqX)EBuLFAJT7h_F%3l&7;YD$UnBf{<9}dre6KxOnETHE{Mq;a@ju^s`^EIp2i8Zc zTFv5%gRC^|#v0!7w{I^NK<5S`-^{RNKr04Vh+?s0;d!Q+`S`m# z2u;ZY=fCTW4_6vMGN zD0l(yz^-U4j%j2g!8_C9@StyE+n6s79^DqmDQ!I|d;+w)B6b=BE)FkD`{JOe0*~R~ zgiNNNUWYa~wCb_-#gPWI%zt5V)F#D>0c{`9suZjv(f6J9SSEj-tvQ}>BD8P;V1rxn z=85DK0IOxoQ-QJC88AWOrF+8o3L?B+^0T#;;gK(LhP*2^jp`1*se6A(qS2%p3LGeJ zy;&xHd{{|o04);f!H1xHU?q2q6bM*Jc9kfrLT>s42#F;6`0!vZ68$jICk!OLAz1ZJ-iL=3?JxMv%3M#*N-HKx<3$IiXB!ytY8~gjVZ4 zv=9#QHcDG22edHInZ#cs&J)@+plv6#tTnI&twJiMz7DNDhczP^Tfn>9mAC|fWjj}H zwvy3yVahr<``375=|Tk#&=kNYD9Dc;#4dv*29F<@4Z_;m6-VG#RsW7Tm~}77u39)-%00Jcd{(Ewsv?rkGj-yL&0a%ZyzFXyZcZZovxTxhKq#AkbNTrfpZxu={@Xv8 z;eh2pJr&2(X*q&-TL%&odB;wVQLo*RK39DX2R3^tJ93|dmi>s8=3->paoLtyWE|_o zqfx8>5@;1eqhN}24v#4?|1!69n34*oOkk7I<3d6VeJ5mAl5a3|^B^mV z{i`Hw4L5f%G6*zIa%vh9v1ZcG#bLd0I2;Z1#5-WI360x!o)ehhiDq2cR9U4%o31+J!eDKX*egD%he*6#L`{08Q=80J@L+pNWDEmuT$Kpt%9ZgM%&E4Q0 z*<)<4jIlcN7di7(+iTF)k>nWAMi%lEXHKs}n+2^F2cebEL7UZ{wKz^_>&@a|4W6wD zz7~;)y@Qq=9sHmg{IY+NUYxRos0%noSSCE zClo=E2}T=!ZAK&{=eUEC)!4ZOW;@oTIo9yO(Pa;>bq?NFLIU~R*$mN@8WZypi~uWd zL*^>0TLR|@ase4Z0R(H{pf(D-Sx`Q^x*I&E2Rs7w+SxO)6RS#L0fwBNvTT$IRnkh0xH~qqB8R3xm ztB=oQiFLRP;=I$Z6xT4a7liGBYH2|^f&ENm8z^sYnM_-WjhqT*Maj+KVZPgyZ0r}1 zxJ{9+M3*uP7wRg5IP__@QWQ~I8&6JD=j(xkc^9&#ZhBT_P}e)ZRX z`ul(X(ciuGmFxa5|N8l-Kl+2&kgvb<^MCvJ1sg@}onQCG!GpRZja`~c`M^l?GA?xf zz3Cw6F3!af*-ifnv}r)A-VHTdfP>cE`$+kO*4cpgMsZ&cwB+!IG@xbA1fgvTR|IWw zXxr=1lCU(O#bT+q&@vU@{ftDDgv;nL{iH<6!yy&1Zg79Q%m2vEI2Vw2fX+GGm*Zsu_(g{qleP@YA3C(?9?6m*4#GhoArCw{N}s@Y&D5 z^WDF^^OYCNSO5B(_K$fbpM3FK`@=6^f*`{p2k9EYPjIn_yrc5%lJuuN${o7e^v zMtRC3u!kX|)gJNj$TKtlNRPXc3&^9O30nCK&Jq>0S{9Y!jq_jh*4ve9Bi(x!GAeK?uP<2vQ67Sr6!5 zGBGv0(R_l9Y&ZKh6Hq|0*1n1Q4UJlxp*l5+3b2uBbn1RFK-}BoM}PgtPd|D87hnA9 zC!c@+Yi2lJUO)cE55M)3zgTVMufOxBZ~yRXU;Fg0{_6d&ef!&g`tDEPT`mklS3cj& zc6B7niJ+0>Rw_M+139hcllG*RAFG}VT9)c7`ocHy?F22U37{DWTAo4%Z9k!<&mRXd z@qpG;s#asYn`<*EQwTC9f-~;fTWA}g-R__b4YW_@XQ^VbKqv!Iz+=9F7H^MifU9C8 z;#j5?W4C$30mq7L^iWQ0WHyf%>T@C@VCQUelNpB9VjVl{ER~QK6LTu{iuJ{G5&Fcy zLQFbx8|ieRDl0Iq77Fs;vm*a_T&xp-0h)v684Ny+ifEZq0N$9u8=!iPd%ZQrB&W3A@90KpT|p zgo&M8mEp^voo4Xs;LtM>)CNZpN1vc&vx|4LOw6_3KnrY75#i)H@@GOD2rb~N&I@J5 z#B&%DrmLh9sqsR}ch$vMSz^yn1q`k;bI`2#TRcLl1o6ETFh95x6qC%ihGo!a&tgii?d&o*Y`t` zg118()FlqlbXer#O+uCGEKEna3=oSxXnM3yo4c>$0P6Hm7e=WmT`h|0nd&ZThosSf zZX>{nbU`FMkBeJ8g%`x|BNcgWqNb|75{uY07XsXFv7ctNnq%``hudf8L?$1av6l)@ zp?FSW8=OkZF3V{g6i)N-_Rqd*O--N8AAEGFPgeZ?=rc=b8wC4DpWz?>-;dg5VYWeJ z@A%M}{>2yHr{Ri$BctrJ=`c{5%$2lyHX zv{@pb=@n?1!~8O6+0->V>$fO3A|0O6lT7onzGAYh8QDR* zq!~<_7qp2WCE_jS=(H#EWY~PLnKr}>8B1zgHoAsV3gR)3nyuHRyn)VykP5kjRy9>YOFeeRd<8r>ct4EQGZogF7=^4ix{!GF90j>flMfAxkjIKKFa-y`r3D(trl!nGCJ<(ULb+ z3d^oj$1lEA7xgqmY zakwX-{x%oR@Ml8#T&GQh(RwJ?)g=^kWLEMCeAI-@d{pYi&izuQW|n;_f;tGB3D)N*lnO+t$U?5j>6&-IGAIE<&s>ZoL-ugX1%_-XHYf_fP? zv|0x{)&J14M0ydu4N6WP+=;A-6-hBGst{5t%!nWn>#(=sRcLjk2eho-#5l<6S}Wh?bdSRn2w2TAgWc}bSJd=7TOzZ)hm|SwphI&pIw@u zvo=RgDI3V$Nm(^7q_K8U21SImoh5DFD7m5|o=SvBf=fURIqvKYHyJ&irkA>jFi#B@ zH0iiHi@{l4OT_m{7OM>?qnc%|#AVYRJS38eH!`~=j#pS_r!-&NkR`ZAr>kyJHL$HlK75P>>6|h8_$Np8;N|B1PV@|XNcdVh0LC})Za6p?J+UU?W6YRsp z1&6l18QSTDHgu|RPb5TLMn4rg(1|S64%g9A%jZ2yNk+<&~ZuEEQ^nWQ*#BX>$GI$MK79s=uAxWB~sOL`xf8Q#2a?wgrnqBmgCt>;`K zW(JU;$t- z*^5~(Fqy;d9ZiLnk2db(72Qeb#54nO(J+CwLMX|~yn2AEJ5n+Y$`Zng-a#u<$ZdTC z?F?ws32igoWiAF3xdm-n1uYA>^b-kfcWCj4bV6%R*)-hVH2V|>K|3GNR?0)tm9Qrh zl{j_wGkccNdD$goQv-2i5MjmJDuu7(veKGj8>~?Z-kbTiMP-;sx{&p1EKX!%NuCfQD!c?il779 zpfLa$&*WGfjp`Y@9kpB>X}*w!NN*XOHM?9y(msxe97Qe;wRX32agc5_OW~}I&Ku?4 zMMfAYWN~Q|`^7>SivwLa=DX?+2rcixsr9a^$TFd4tt09Ks&r)eKsSp671Ue?_cQq7 z&~%jjkcWz50k`I}9~i|{9#O~Qi09&XgxXEu+DuJV9i{@<@`R>{`^ACkE8DIIwA|rP z@w|mL-a;FE-?ahla8DQ^RPz>JZW(olR1CmV^{Fy~qM)sE_L11)K>Ep@dlwad4&3 z*#(}@s-$&rkyKzSXle3IKe`aw(V&iweL^|wKC3}n+;|j0OQ97(tGK8p&%l{;RtB^Y z3|Lan_I3kp#;0uuw5qudx)Q%qQ%Iaf8oikyUQ$V3 z8VLwglnb~lVQ81|Tn`$phB8p5s7M;*{8{-0&vrAf>qLp%!l7Nwba+s1iBeQn;O#DG z?CeSJ^ztD_v(nkJQf?X#XkFcf{^g_;8lh!3;xXMSJJZHw8@M)fMo3}$PzDJ;Z14`+ z@H(^_^?3&^XR-a)(Bkh)mSFQ`EDr3jI#?d(9oQmi)$c&W%IGRjQvUM{4pRa_J*3SQ zguq+TC`Vr7qy$!>*h)C=K%6=EL>nn?C~U1GX{6T1G2qArbjXLpt=LtXDm+h!3-#BS zM(S$uWwyD}YM^;H4`J3>4;zk5loJ_-h_#qFBlE))vyxU3xnkC|u!_hd5#!IcTu{5n zMH>ES3=t>h;)?@~3~z=ujKxt;IVC|m{!wv^%T5BuoAw=`oo}GMz7blTgh?d8Z7hxh zTDDpr&@$>SRL3(+HkY8$02rlwCnoO2_w~kGSym~sLxWj*sql6%MTc3#2JN3d3WYAD zxZnXz(=7Vg?An+VjI#siSrXgo=c6sX*y1-6j7o1(;O3gF1j3}?@-LjgZA$<>&Y<>W~qi8 zwh5NkTy*F#*_-OTXBRU-^D`3miyGzyZF6Y7P=T6=V+#|F+L;~1KJCG z>=Rn42XT=4bS1YC^L^n>h~gfqDGgTy+PruPw2NOxdF5OVaQdlxHUV z%CqVK&D%=Y|9!2&yOhXs9v#YC=S(8%cTKJV#9)KjE{<-s+t_w4_eovPQWr(W=8=|o zq57OgC{^DiC~U2g-v)2M$DHm)jEI41Qo(zV(MX6=8amoA7L43I5J&vP81k_=Wn^`C z#UL9s?OC$4UB5Seb0P(o)d zp$&p|eHGfqo(AWN-9ZcD27i1)TOC^ENx@ozzR3-=QX>$CLDZ=qF_H2yiEZPYyq zo|uHUq|_k)-=PhvZe&U>@nGs>Vy@N$i^F6MB`;_y_J?O!C{YJOf!C(Bo}Yvv7trQ#NJeI$AjCF<1-(DMwwyI!QFnwPg6{y5y57 zSenx^*!y{CT~`jp!LyshbRH}STq8UJj&#-10jYZO8e!6KPG340#Zov~lU5ez!3%%d zO`>+Ll0jLx=EDyjZGe?$l(sRT5vejcct~DFqyj9}vG{L`&q|Xj!2zv$;D%#JmFt+d z1KOs!(kHalp^buePGjRxVx8ZN*wFW#pq(7raza~AXwxguD!+88g0`{9>03uKDoN9% z!3E@?8dg=2?LdFO3d(f0XCJ3qo9iu_Xagn%A`kr}O*ZPKCaRh*rm4Fw8Xphw0-wTN zc)!Nrgsc^Q11oOXm!~QgToeyyXI{b%G(@CicH8NV0ne-*Le!75$|zvn;5DJE-L!gB z@R><-kboNXoLhBC7Z{(YzG|#tjax(cUMTalet3xJhda6C)Lx1jbZE!diqa>ABGKjm zBCF+OO;o`{J1V^)Th^HwW^71kX=vCh1!G2N#bUaHw%tN|J)mt4ZE|Six{!1g16y{K zI>&P~jGjC#ljVd*Z_PZQePVN&9cU-Cm9t=wv5wY8en6WzF#6q z9z;*%mSH)Ph-y%wS~!!)|GSuLV=Tz_Bsct8nW3pg=fx~B|ojIQ2iKrH*9e(Vq6tv4f)8gE{4|- zU`95r#dGoZ>I1Y_{$sLDopJ#(<_Vg2^Aj zpMjK!l&U~}M#Qw*CAU-tl&VqAVu7pZH5fHoq0 z$_!>#vR1v?lj4$aOQYy-r$u0)!&@qw%Ja1i?QW6{(pVfsvPY>G<)OK(#SsW?JE84C z6NY#@BNwe1F7b4n>i7(7ronRu=^SG~ojx%Z$33(uI>G#aR4gERlJa6WUQ0 zaB*gdlrgFYdkFLn_Qkk6hc;=LHLUGgr$cI)VwC`g$y(JNE`^Oa$iw!g8EQdY`n1`T zi1M5vZs9E37-+USY5%z0NtzAhfFaG$F$a%VvIY7_FoKJF2J&M}G&gBC1@QI9Nukgq9@*%9?zDh8%lZvk$_3#l z!o*qGX(W6g{|AZ&$y0ENFed<64Ih#PCn2)W({l+%qL?dE71Z`GUKECeWfPN0MZv=4 zHDBGjWxkK|K|ULxWky zw^BNC=vJYyN{)%KE%b}13X;Tkwc=5s4=G8)HF6pjT!!K{_X39CZo{0Bx0xHsL!4x! z{9-uDrc?6Sq3sr0NE)b>dqCR;v{lf8yUvz6HfPyDGC}Kt;MZ_MYiX`%IaoDf-auO& zTIOR2ZEHPj;u24j+hiHT*d;~VH9AmbfC}87rHBw;PPWSoa2s0Hs9q0RKL^WNTVCFYsrHyN8K4t-Z^^mseqE{)C>X~yST3+ zy;K%!kwZ9Z7o7pSET^Zql&A`$)liG0srP>@j=*js7=bdPUvFiRHx#}4?^DRLH?(eY zd6Oq$<;wcvaBi;ko%?Av59}j5rEwteV zS}}aEI5-oNjUFffC(ky>;p??UXY^c@Vn}0gRMFz&;9ndKSCSh7S+kISw@NcwD?6zW zKRH{sO9Fe^8%Y=a&|qQ4?g^|Y4z{#!HzVpIDZ6B(IF1C;pRN$(iUsg;VDh{Iqs-zc zg4nT#Sx_jyn^iD+mOpMzE?)So=qkAw%;dWYd!ooQ8I)*^IjD&DY~xOLZDH1^X^mZ! z3rgW$lwXxAnl!TjBFPgT`J#eCbUzlo?wd-^*C1qq%cNXV1;zFeh>RObtYuexUmnwKP`rmB`DjUd1+MRgTU zMO0ozvn&>|oM)Dmsf)&e7JCyP9p-x>-?N<1wr4xnUxOCLhyG6zw8$oe0qw&bw3HI& zj2=`u5)~9y&@eYr+8tV@p%(53_RAG^CD>{&>;p2O5hH1WO>k&w3pKs&1tWOujqGwt zRR%^@O4YyLL^x`cVxu?e<}Q!fBBCAnINR!jj4}z?$avwu2l2L##&6FBj=G***b{v$ zXz?Vd__aJH#4|YooqycXHOLj~U0UPL%<*}dX;|o_79r)e>BJZJSv-qgN5L9|a=6c0 zZ$7I)QAW%@qY&AYJSYUkC-^3pR*=lm?2{dwIxN?NnF^*U**;!hgBD>@k;ni$=YzMg z=|lvymlN7XMaltf4$c1x{vW625nApy>RL9+A1PpgPze(HLZ-SF@kM!- z16sNsRT4UO2kXrpP&S%86;jFkj8sLt-rWJ)xsxvrCfbl0#fPuD0}V90T^yb*ZbL_k znOzW~K;ql3e!|-wuy@OhCgyiHB(pEm{T(zHS(Gc7$Knu^xRor5cVNa49@(V2H^;n% zQD_Z3bjfvQokV_>^9-3vqvVlm7KG9D%Vg)dID!@jg=M?Tf#bnXg0`NEV?f&-&8p(O z|K%21Y~FEl)#NQbIUS2*%!;d8wlmYHV|*NOa%h9tMw>%x=LH0Z77BjgBJG+4ttYAb*TFHLEcjU^+Tr$#o6Twy3ghgW070EExeW;0OKEUFob1Lj}0I2Q+s{xsGQyZ;Z$MQU_ z%HQGAEXZSM?8WYqBnPzCn5RkRC$!0XW9?CF46(XMt0%N#4@M2tKv6-^k`*S;+pyIz zMkXwp=Cn>e{)TiP8V$|#w4nm9z8Jj@dL(6RSo5d0u|pdPt-W%UR2}0&FEbW3qy({B z)cMKm&dv@kcy-#2$h_99E^C_+arIWO&NCF63t@C~;iG?pOT1o_cjq%M1oeWNR#ex6 z#4eUTmpczyiOridXa}_gY~+%+$O$w_0!bY6G{oG%@{1an!y-nI2XLXJ3=3MDn4{Qp zAXEp}<;)=YI4dggSmsW2B0X)Q1;U$Wc%Mj3r#wVgJ0P3-$BYaxB8mzr`3~Csgtnc~ zrW0CnwzHs(9GfNQWI(%h4Fz2$A6XzShbbLmJ72d0T3WR#{oxZ@>Z6-C5l?8_4Ya9j zM*i@Q7J`Igr=5S#YMhc)kvvU3MwKeKT-9HThE+&peUsJ z#k~oB)C@SQ7{~VG?uC4I4aRyo#@jYEGk9Y>udfd(g2dY-h?9b|-ov-)9wkxr-?LBZOQ9vUchFMnPwbNuT7~b`rxJ;7AEp}?wo^?6t#+0}i<0T8gdDKg zSKh2>##kIlDwa6Bmk>PO;#bVoM<4SB@^*U%2${yTNJhD0`D^mqu{c;&xs)n{!tvh$Ah|wQ!~hG~h7!6>)_{ zM_pReuR~jdL;K3&aA=#LwZtq=&&|a_MWkagPSMmYv^%WW32i%|)zO07aKJH4FN)A! zxbKuYIiPhu=};f5RK^SHo3fQpU3$uyajq<+@Qi4si6ZEIu|R6w(RD5Y5l+SRN)IAE zyxgwHrxh~bSn2UO>?v3@Ioo6=pJcn77kVqS4Wu%lf zmJTH*kkEn_NALJGKai@MH1UPXP(1lPFlH&4nJ&euR38@+N{MNdqo!7e z$1+4)>1WM8xnNA0QfeXi5MHJsJhG9HtP5JWyTomQs%Jz~%n5BsF2Q(0TM2DHhcKMb z##4SUOK;*;XbWqjgOpBaad?YgF>3IHwtyMu&@yCa&hHpnl{Gu?7TPK)NgL8bu$f}I^ zScytJ+!5AV+xdjJW(YMVrD-*?(K560?#lHTRlyeC=-RD;ZLJc_P^0n*t$Dw$`%P%W z>(B-gO$2QgwBdv{ak#t}UmV)}CD4{Mpe>SAgY=PfY+i$w9E2=r+tQgv31Xbv4z$LJ zM-9zoz9@r6#6U(BNMUDX&4Rcc!3%x_#Nt7CdH&>e=F!F#|uAF#saA|A}Tg3K& z!nxfC#OQadgvt>yMXkJDDKsW~Ax3;9>B{;hxYQ9DLuC(jbED2t4FEN!jftJ~0v-Bb z4#{D$ZZA5BS06OmG>-@|m-5~W7&bVGaOK2NXVAJ~ae$ICLF`vg3g2#0FN?I?HV^gC z@Uo1_U}6d-Y6?$54N>SKUGAXG)kvP`RuHuL2HGHKA$4O?grtexK%4gL@y-D)TlC>Y z2-@^!XxS}SyT*z>9?%BTq$;MV-a^};5hIbPqG>DMPrhphVVG8)6b*{uN^QwbAxSyo zHTV=gJV+5?7`t&=Qlu3qzTRVhnbp@>|{nD5QPyHo&B8gbdyFp6+NDuZtE zX}-r{fT3%Z)w}59-?aJA&iu!zHW%}YMdIB|g zM-i%_E(U+zfzPhMk23uSvAB*yRBG3*7u<#vfp}8BI9eIS0Jzqg`6&9CX9OxmdBE7s zV{tfx#(VuPb!hX|Amy^rDag{yd?XeaN$(nIok>%e?x3{?-I=aTgOu(fN|Zy7G!7x3 z(5gNDfHoXccPt)sXq#VOV^*0NTtOR@*dEXZHIy`oIV$n*#T`azGaF4;GhAkj?8!|k z-afhv4TZy@o^9M}J<;OIJ`9R1e&^&^BBgKcIB7OKQ!4=l}t^S=gh`No!C`Xc*A?ZVUGGln3p>TD@q)5dfavvs7 zkVQF`iDLGdeK%m?;WRBApjAhv?C6FS$s}VOr1VI@H}q0SlV6N@hukq#X?KdUuRADK z2ed`HsRy(>BpkH#1ucV>$^_@8l z80Q2?aaZ=0yL^s&>zdIT!SfGpjKM`^Rubt3JZp6rMAal=z`$!P&pW##WqEK__$><7 zU1TDY5QI&eIa$v3;3~p+9T_Ewz|OmJLkwHsIvkzY;VKH#j04JLL_50_I1C=o)S;~g z?Q#vwA3k{I;>ywzB%bYhKlH-k{%t;M*`-?+ z&D-k_N+OThT1>35jd;^ob!GH6#`ip46qtvD+@3L8ySt7W$ALE%ki6B6>jS+zWE*)f z7fKl8+$9hX5)GNYZHV`yO0gkQLa|EZ=YXEB;Qg$!g6v{N)BG&<7e@RlcSZBXnk(2q zEZE9+D(=qq5a;SsF@%89|9yz>Iket?PEG<-hLpNYuR`0h6Vgs-*+6g$Z8+sw@Qxw=qRWS(_=I6OeQVo^MEg2a0Y()#C8E4o-t~ zW|?{geJ}$ogl_6s96a?r!)Lz0>iPrTq`V$u4$z8BG3PP=nYmNx4qoKYUz^Lux|R%V zi)pRS?n23vQ9hw`iPaKX4nt-;>j5p7P-OFhL^;Oda6Hb%;p)<_Kr6!Y=(c8hPkKil z?Ni6>4q6sSUV}EVH4Ai}FgjO;4;?`=p;#aTLKjZ6-)wC-a7Aet60Gg}au(VK4d&N8 zCMgnez$*_zJKL8rD{6wz$5zyf`Nj{klsZwLxuRX(7ssX-S07u1BWh)q0R9>qy{I-9 zp`l%UXqeU0Il^p)rm>P%Gd$ahW0|V_A!&T8xZTF$Z^sl&((xilc;^6Yj_pPzggn`e z90WB}QjS!_3LggyU|3^a$!_RW@>QP1p)C~sCbXHOCLG$!0j;og;S52mb`w|ro3jWA zK22HB+Cf8UAXmCVZWqwD{Q;U?fYvmYEQDPs0h&)}n?oBM+A3%hp@o_qxjT)@-uTH( zIy-AlYUHwu`9K*#ROaHT*QOoix#sm|kRvR{#?hfCfxLe4D5KKtNT zPUx^V8YzFLggGU`Jo&t)IGRv28o~U6*@?HCn2NTv7H4ut6+t;n29JNo1*3w(t!++Z zMd9rgXd|IzGAe6MQhFU)pU*-{fzh1+ZJXEz^m0urnf!C|{5zqwPoCEmsn8jm7iB{n zT3U-cXoEu=18ud91me1*%zAc(IWWOD>KwTX-!yrXb4WEX+Yc7{4az)9NCtjyNSZyR z*umqvBsDfP{BeFwQa-h6s;ft9P1EZuB+^h6q2vxai{!QQc#C5eO&ru=QX18$jOE{) z(KKk}9O}{!4<4irrsl(#yX_m2qWlu$r}dDCfyTZ!X}7BL6pyZG;6WrkFFW80{oBxs zqd9KgS|n{sCbCQOs;5};%#(v*BQV5uK zMr|ujnIeH|<{cbEAHtC6iF%bX`|eTr;z-Bhum@m&9g72=y!Rk*&Sg+SfFvE2C&+3taNgbx!Sy7i=@$}jY~>i9P?ZIpiW&hUER~k zbXubKgRBTvCH%P1NAiL7wgh%EJGv(ckoF)+CrQ|Akq7ZODKJM$Xi-4Mw2LNyXh;IY zhn1Q{aRo%yq0{P0b|7o)?GSghH$Gx$1cF(mpwcD#$a9iyG?;4_d1E6tCW>R{O`vR? z0tYn0$&f>9T8?r;F+v!Fz^}dCK$|I4p@IvPP*|`Pw3jE`76xArXoF{`!H>Ya##QH< znz9LP)p%$%^+@H;yf0T%-8CxVgqCnPw23SdKrph5W%=e{?;0bLX&?1Q-XtNOYfi>-Db>{sSHe=)a zN_hoZhUN#fFk9uzp>5-Y_F0v8(58E6U1j}*Rwsh=VGB1aNQIHJ>%k84?n7_+YR5c4 zRFR>G8obYV8VNivNRTlkJ`K}BwgT6sCS{R}1A|_dG@#ww?Gd!sH$uyS z&6P|~8st}?^_gDPq3v&gwyv|cQxe*VS?TO5figisReOzWP2K}4olWQv(o8d%O4`3G zGANa|Of2hKN;5n}U@rfnE5v-9gJm*VEG_oX}Qj)*@AL3+)PMS9VxYi7`lQubt2a zFh#C|nnh@>&D=cmAUaQQ3XaA_o9{N!L!@87 zu_Df43rUo!z_v~@3J>I{_57PRSvR>=oJ8_5=B(%$vdH5Q z>_rdGnkhb^#qXfHbV54j2@|Clx!@2im!DG= zil52j#>*m0Ma=+ZjMnqHcM#I{ZuZP=L3=||$r$>Uyr|6tCH~D+dQ-}V6uaP^lhsQI z&8d0S8GI_zq8++$654>aCFZ_-Z%Xn5UO1s0dN>EP=?wdm$K^xiz71%r+F(v-tA_ry zbPKKIjr5!ZZ5wI|^bWcU~R8si`S_AAIIU9b8C{X zf9Aiak>|bqs8}+D!t{AI7eh9)?)0tm)znO`_Jo#Mi*BR_DFDH&?t1YlG<9_7CYtyx z&N1jd9D`mocqzF8mRn5c2;w-n$eFC0E-Gn&dqjQ-Ih{FhsAxiJH;QN}w}#jCsD;7B zfnncjs~wAo%yF=YLEs{TSnffU+n9YIxGj#A$FM`Il#xV7EdU|3#`KOSwBWuE-U*}(ypBRt|>R!(1-_o!}wmCjFLe|pi(hDBy$PnzqFZ+MZ1z^t8}%W}a? zKa8BN)U_#Ss@F&}>Ot7TDO69uIAUqyKp4R90Gsq7`#ey4a?{|Os_zk1AM+G><2DKj zypBoM09mS;{lR2xJ>xk%^6B3|Yb)K%SLI-2&asayBHTcWbY(_CCOiB3ss+J-Y=NS- zxe$|97|swvJH6ao1eDM=K-*4enNRI#)+Mx5P7HV)c1Kr6@8c~PF#&rpW) zAZ=0Yp*5ES@eyEV%65Ycx}22oZQcZIlVj{mxk|Qz;lNe-1f&-@xeGJ3*@<@v-uBkq z^xINVe~9}+7{mh&Q^soKqrtv(*Ig*|;(d}?rzTENVu?v6%3|<@@&5b7SvMQaPAYPW z;knMubI>G)u_`v0ux!d9>Ciim)Z&V>M$ZDwK5`+QYC~mEjv~@5aTz(xBhN)6dJxnM zXoG7y_+Y%;2eh1RiQZ>HTO3+wg55wngysdUS%Eufom*f1R4vT+psj}7Woo56wE2Wq zY5+()u{G=LwmK3Gjr8?ak2_#X2A+>S_M$e0q%cfo9HG5tDGYwzwT^_f59}z7{1#q7 z)g81jM9(~LgL(*xO|V%-Gp_9db8wEf|ex?sb0|6h3qSv8yU%}=mi?=y6ji zTRt#9g_&1x?J)k69Z?J!BF4Z5tAlq4&bxMdR@RiI*WK{nsSTimoMWwg3ZCXYu2B*C zllsS5Llc_F>dfBVLwO6Zz*vpBS~8qU>Csuq^0AfYbo zh-pj`V)Dtv66~5hbKvs^s7>O6(4uMpXswAP-9igxLT+sO)FFI;DO~f6P#*gxFVl3v zCn3IvGpZ4DNLE2c9t{eOLWoLOD@&k_V1>tp)HbwHkhEccT`^gkC1o{^gCn^l@(d*i zX^TrK0a6`VPmWpPtep-~`kZ0LAF3?<(nPa_q09~c?9^uC>o;re!CV#;>{vTlY zleM9F9m(9p>7vOHSuM1%iz}g}4V&4krM8btsW;HtKCqH0p-u2R0Bv0%xFDzfgjTFe zZ{pdN;iup-j5VS4B$%r!WrsGr0xcy+E`x(5rHpiF$3eKDgqaCHj@3(~zo%#Wt( z+9tKSDnGSwhJbt+gYiJoS51Vi$O!im^@s8Qk334*Ld5=+(#f9y&D5I-$PM;cs#o`t z!jKV0orL|a70;<26b|c05$t8i`xD6;?3RE9UPOR!^mN~P4@=D z=Hqp6%iE#x!>lzNk$Y$lS-#XgoXX{ZRyG?cG*j|`V=|x}8H`t;RaQl%(=US-%FVik z@>nFr7vuwn1+d9Reg^}E6gb(eW_?LxkfyY9P1i)*(ZAtD>1DDOO<1iT6K|I zjZNg}FsLkJ*K4GF8yc?2Pgszk$v`X~-7Jn)9?!ZoM^VC)S4%^nekes2y#q;gk?EWS zK-y;0;;4fuDH0$hwIutu=uA)ToP5$WCWZ8QyU)EVbgT;I$25xj#UTO7>P6RZOriA} zhKeAWDyk>6fkzJ(M~$~rlY>LsPH6Fw`+)YC?<{C3Mg~`#>15W4Z=b7&!Jr;ymb**PcZonSCsltX;|&^#iEo3e?(o2O5GMm>z&=Eg=-CNu+`>dDz5LSC z0u4_F;@JE7(14cg)Z+F<4W0c|>=MWx!l?#XAs zXmVR^o*Z#yR&{*LRG5U6FxUzq${?`GAWl9Zj8pW$JBAvHbb8EJz-C2$kRmF}LVf$0 zfi*Gom}4bdN*%FYZ_ zi%3T7Doi);@eQPuqWHhKn4Xm3EZMRwFOu31abho5Hyiqb%(a2G9h+;Q`tVAswS5k% zl@yx-sjNKHNx6kK;Iiif+Db<4lm@g>nQ%pm5MW+a3UcWHNEcx?(E%+cCLmV{{w_U= zg;255OPXiY;)h)r(9V(P2)GOd{T70j!Xsr20C06BNHEyPqhnz?bolC!hzVLGB6qX- zk0Su`P$*-&y4QG;VkYm z7c~jd2lH98SC9WkISQQ`l>@@tL2ev!0))2TKwH}hEvY=cy5^(02v`<>1GFpwJrmm8 z2DCXJr<6lG5}#9JMKQ3a`7TAxDInY?f{9z9BvnfOYHgL zh%POVJ=`C1MzCwoAXY@RFyal5X;2+T2m0>*!mJpS@#W-mh7b)l1%mJ)FX^Ue#`;BE9~#jOePBT|^Rzh3Epv(L1uYoMqK!%zJQ(6AVpk$B za;Jkz1cNV6NRm zD{`M``uEU^XECKR7DsNQ1G9`_49A#gQPTh|D!(|Qk>+OfS33<02$*K^%=E-vvwxTj zvh=DeX6QLs_-$PUyUMSR+V0pv#?8kVzr^NYcAztN)zDgnv(q92=&41dYdNaN!ftg) zx{C>AZH>{iYErd4QLmNmYN=ZY&g7>+G=E5L%(6*CAki>Lxv6w-si{AWGy(c^!u_Affb;#{R zZTn73hEJegN>;jCehbqv*_$w#s|WZiy*y5z2Obe7O1w}KwIvhZ9YZ7$1b30s5*-iGs=A0>X7B5 zJo}L{Os=%-BLygNQ}P%P%EH-L9K9Z+seSuwF3{v0zAj3*C^AV(U8E8iVT`hG2*8;t z-!kbM=$!?&p1cJSR)-oMX~h%)UbX3<)X1S#%I$I1535qGFsU>jEVG#!=<2ePGGXw&P^rh90`WF*sB{h8>Da%jo)o7r^GH9;o7+!0%| zZxcxf^cJG@j|14izf`ivEdLpwCu)Fc0NXZB%PilM3o^;ELpZ=U9V9 zJh90h^nO?nP3dp2TuM(BA$EAa>n zrX{qE6$ncx2SJ+zEwzc0>wuro@*&pKV)Cifdc;WIETFg7H zs%mC%NeL~e;gA!=hn>(`iCyCrv34}^en3k{;vU+1KpRw;&@kDZYGDx1QB%F3)iz30 z^p2H%d-S6nT7Y6fF6GpXq6SqTmlM@=${8gP)IxUB3kcXE@1tfm>R>)EsEn9v$6j0) zFErNo%;6{zvPYsBtmL7x3z3>7KGYE-PQfiykrgS0ES4U#f~#`J=AkssU(On{@lyFV zC=W?COq#v)Zm+2MaI~w%I-3s{hTA{+>^cm1P-Vix(D*$UWx?KCHIdK<%Q2OYl1sPM zAC-`c57g+|DAK~dd7^C>vOeQRHME&?8V$J@$)QbD^+{fGF>H~wrCc;xrr?cHVXp|< zd_rsW>B3y|J+#c|#RFQqb^GF3UhN4jYhBU~_Ii`x%mkahShh z{x&U5)*%p>d=WKDqbbF@)>v=6REqWp?Xqu*Av<5xq|CuL<^QAX-Et(yk!?{D;0yYZ z^d$&zhkqs_29WW6M$#jwS?z&dTMtU^nbi&4102-us*Fh2a*8yXt;a=tf!r`z|HfNJ zvRnxFN~!Yt)sIH8zcLboh5hcM#v4gi9|3wVaIitdYrp45lrJG#3af2ymgX0j2UIh6 zzWmgykB?|Yg#Qgef_63&3d+pBO$A=aOpAN`gM*>M{33a#{{5}3CKp!|#|14evJ={G zat16L>|;W^`d0b|Ewup1pZqsyhkGKQ&{CjlX!Z7BCTM7@`Z+`9FR;S=1KRQ@v}}vO z-2}B7gcd&GO@Om^N=eqfIis?Vd39z}Pqp(E3w8Q>J5>WM=?QF;tQVE7W4U*?`2<+J zerczb?>ftk;q#&=*IW1)xyWOXi-Y|bn+JHRCMEm5II2FxUQA8YL1c$V=c85239&fX zGj$^di{qSO2@n3EZ}2sf9777oBnsg0q=Q?}wsDmcT4LX{I1Fw216tY5^x5&jX!--% z;sECf?Xc0AYO$l=(8lKU(8T^7+HyfFTDAxrUL0dWo9QkrxPt`7C@yq&PjI{BDh9@z zDO#Bq0qwd}SSRM!8*O}CNo4QRK- zh+|S*dvh(gO6?$Mu>-Aw7Ic!(vNCI`-q1Ec`w+CGy9(MB&>}Slso6ylESS>%JG7)6 zE>rYKM#4+bvVKDUY2FOF#D|HWBQE((z2HSI#@#bvQ0igIQ)%ejO*l00Uz|#4s&euxTk^|@$R~KAPKW`7KeqJWZ{c}Lj0x}G=OA~)7RJO z#3!8m*?A8G9gvkn8GH>z86D?p!@~F=FIx={?YMw;_wZ*?3(PO?AJ86YW}G!vHaE0M zCP{iZFKEjm0`jwc6TPA32cDA$bm8(} z&@La)jtOndwf5d;^x|{;7ii@-hZYpWixb^oC$yS9z(&;2W=($Ipykf-0d056Ca>3J zKEbI2BY(WyYEp_me&kFsH?M;m=$ic%a9FZ9vl#+9oE49_2iDYD-idrwpN z3SUinY{~nnc_w@uT!M72I-tsB{C9*Dt{i2n@*+2)%7N>ESH37$)Cyz1Jk${0nnE>&(Lv zgJf_whC}gp=Wv^fFRxs_^m#nCkrPy#U)+rG&h`08luB!$)Xgd%D_BPI6_@tUsY0 zf|kS$K}$FC{f1WE=YPrt?fDKZtFgxJ_&c=B+yt~Zz|I?5Hj_bmk??9$jASyjX+mpz zFvV>Rv&>`^Qs*pE6l}ZE!5r(kYU4rLQKH_M-diFWW%W1bje}noz9j}si8`h^wS7Ke zFk;WLmEvS>^m)}jNsg2Ui*tAWg0>S{J~AV7 zbaIHa$NpNmp)K#w;@ZK<-GtV9{;yAHpDeyLS+Z43({?bSt%kPx%&hu%yUl{QyqoCA zyo!XE2-`t&?Tcauf5juQ)yrGmcXfM)ZTd1R?V%)Ij&-Czz~>-A{i#Eoi=%vf)!Y65 za^h7lY`1AEbU>iMKTocev(6^~u`bU$f|J3@Oq$5kf|(`G`kchrxi}QGHst*i+Smjqv;{0K-ni+@ctM*M zJ1HnCii|aW<(nlV`1h9WG|hDctz3#PXzSNkt(TR<3>3JbrLH(OI%wg;tL7ZK$V_OH zgr_*ndhE^51ucQ}!0rnX(}n<@$b)^w)`QGiPLI(CUiYdD+$y^^_GM+ri2LOn!YgyC z$O{{vcC0UVYCw>M6A2X7kjixmEsC|j>;Rz%TFLFL{|T0~#Cp~0Am&=|N+-Dn>2ta+ zMtk|#m6nBF?bs7X&@Tye=?H2A(_gT7RfaAnS5O*sB`$%Iby~8$+CBp`N*T!DnSX4x z^AO3M43liumpWE&(C$IJLUZ+nkv*Yh$raGXRRrQoT&EVu7FH~_r0D4z+Qh={g0|Ae zwoRLHZU@_oa~VSWB(yjy!TXF^M;s;}(Dw0IH$(fRec>vTE<&3KZ33Sy{uBe}(I~;! zBnOH*XNmO5Nnh85wEd2CwdwaMKqrm{R6gqM^4*7~hHNW%`so*~;>>kjq@p%KZ5cg# z@u=i1Rpe0Y9%-B@u`n?uk%vzRQo0VYjb9PoQV{{IC+g@4!>YW<0x1HPu*b|`cn!&P zp^)!wv-cc3pNd>NVW}re`kl)QWhbetv&h~yx;_vcRGIyv&|A90o@I zjZT8e&~`yvC$wSvH{@1eXyZ1qS;8!67ko!UPC1z@Qe7Oi7KPZ@KP{5Wl_?aS%aOe*nX4Z zFnX1TH|6;9Ywm8b=V?PJ4}0Y?fTMd+=xGtmK6W4THa}*u#@FY{a?w8%mAsi;7R{-p zE0MutvL3uBInNpQ@}kAvc#(M#KSfi31gVCBYPF*iw4kdAg%qz<6|iYmDmvAJ_+GE6 zs6VVTkn5~gCbWx2>r9=*v0`Y4guL(2rcY?w8??5d(6SO0NQO4g6lca;&djPi zg>rt{qMy29zo6|+zhmQMkdn$pCS74J6FIVU##FH~H6eNeQqmUF+m zus8Q}XmRjD{&R9P&VdJp+jtx7yWD<-cCLDPf>*b$&L7vSqs8%oMkgErmJTBkxO813_B7V+Yxw5f&izo0FKwxsX5IHXxd-c8Y5 zqJmSv+>BGM)t}Jv{uP8}c1BiCkMOF0DK5S`otPup9}$$hgJ5GIkI@c&{h4!IVI5OA z?a2ylmW5vS3!fb=gss1DFwM}|sDO4F(Sx4DoB?HpV()+G=B3EXxaR%FHE&-jonQ(E z#mg&9SEW-~Rc$AZNVHnN>z%sBh%NNAdFs&8QC(NN1F^0SRRs>7GlB?;U8?bd7j~)Q zX1YGZ$+R<^kkNVUtb9}a!V%oe?S7JnZ)hW2FUGd<9Qy~fZn#WnNqUBb)At2!CO-+9 zb<|&tjtW)IafJ57n@wnGjJ&eB6l49WOAP2Nf;J0Usw{B=(%|=k_UAWdggd^P8(Q2X z8+VWRl^BnTWgq3lI@(1dA>j|qP*c$#6A@SCBZuWm;|W6&?~YZ8Yk(6qVn<49a_Y%1GQ}UQQQetLd%7hm9o#Tr>1Aj6cK} zEWT?G`R(A`XsWM3AIOV#ZP1I7i5;fMpT*OL4fEmj-8c-<(o}dD=s0Y%5?YWu5(B`b z!oyy&zVUMeEsNHpOlZdqZ85Zcy`Zgvwp`Gjp4EOpD_SB7xC`1w8y{qe9h#6N+1pJH z`6@f~F6k+GA7n;JxWrdo7RF<<$LsY37BaT`mTkuYhZ1OKm4N$L(&ZV+8+vkHjINkA zy5f&a0e<31O*cTE*sO(GvEl!9`s;`l6T8yOadN=O^xRc8JFn@@ZBX&_$L)&D+dy)9 z1s2C*jwI^`|E1+BK# z6>f(US~b1dE1%GEEx$o~-q1#|gS-_$D;`-=Sj(g**oU56%X1QTi&7KB+~XaiGQpBO zl9y`zt_BmbbE|a{ocva~gJRNHt1D<$I5Dj|qV0-omcdm3!hoB8bB%x(h_Ak&Xww!g)cz*&|Yn*-p3>J0w76*<^$l0NI zIp>cgdM?qTruiL@8$bGEH-@1Zh@W7^(Wxh(7^AD}Bk8HaR7uqz7ZW01&ir$J0sr#m zn_9Eq4nL8yx@TZ8?E-ZHNLC}x6P=;vaM|kPV{t4rMgX8dU%$Yge`#@4HE?gQhcO+E z%9SxZ2OG*KpU|F{$VJfBa}J&AW7Z3z7Y?mGcPQj4X(LZuIY`oAM?s5&a${e%%8KfL zql@l=DBa}~+Uvc0hqhh%*4G_+;6!VTB50M}EcT`gVJyZKBZz1?>(U&C6^K%L+R0q~ zi6FTn2n;0x!}by`Mu!@zKSgZ5hE}G^yD-S4eQFdlpmXyRd{1ZTl{pU!bFQ;uag4TH z0men(Afb5u-RT*nZvxHioSZBK8!mYDtXLeK8evSGc{N_dy@f3xTeb17J=r8s7LLCp zv_X}-i+&QZ%P6_F&RjYEtW9&xU zS!oC?XwAXmbc8Pgp)CO|O#N6vhsPqXp-mPEf|ky-8!okw7NBsspe=y*WM1h9w7+GK zX=oWX4rp=q3R?D*Aq0d`DY$|BcMRo?0PJeERMTXufrr4Z5WH-{&L@6!P`f>s()zICQ(LzXXw3K;Z9X*aZ_^rHF_ zw8-icv=+BuY|i`!aC{wVM9=SO2|QfA_Pi6%08k1@HZK6&WQ6iwcxC3~xA=A#-?U$qCnR|rpcGMc}7mQ;=jI~qT99J}ZKj{Mpk?Oc;(PNs zp;h!H(?@pYR9EFAlM;u$%1OX`x)z6S>)qDanLJ;+=c01n^}DS~aZe^4S{&sU^D7WI z-=}JY){N6M^6LMSq}{rz0JxW(RZSsx;5>nd9wRUDB&soZpwf)3X?P@CE5x8?9hrA@CkKs!}~cyauw`>o{er0k#xZ6dT?x#j#@mpZmF zqmGgm$17;KMLlvhuclLrXl^tw3RWvH+!D0BCM+WTP~hmPJ*I zg3}X>E*~=hd$3AYa35ct`iO%P^5B^Y3^fJlylPwEt3fzJ<0Kdr`)Z9;e8Dg63wnj* zhm!sin<}RE+fy}bRkv_w)EEzPZT?{BQS1mr&Y9GV3rD9bkCLgdHd>o;i|A;!V$&{} zNi;T&;Z~b5i+IU4syZGE9m9?RyoUJwY7}EgL9be*B!*I-4K

B3h^MwuTl+!%Om?p<9PcPTYnb^yaBrbQd{lWDRpYf0ffWUDG@ zvzj5vw0l82$_KQXz}P~#{VTNn4O%rRhM-Lo+Ae6(860%<n1AF3}Yr7I-@1asH@0#tFdpq3DTJx*6oC%76wglN|lD(Mh}Zc zFx?6t<=#CdM5U&D5?aeN9kHupVesaR9h>&zUK}e`C~8m3qnBSrEROJ>McIn0A^)~z zcx<62R!wFLo8s4LjIgbq>vM6484qY5Z_v)g;kb_>rHr8M_7Q{+E$EE@1KRp;(DHao za~vsXhr3&JHUrIgY`ZE0_>HE=fP9oB%45 zUKY&*6de)<+e@SJaltJOpY>p-PU`eGR#8AImZWGi9gGfv7$G3Ap;S?6!+BK3hc5``LlX2bank!g%fpal=&CD1+}58lWT!74}gtz^q?oj<9j3;)Ka=Y)#=ZE6&RANG#UYjGSTeh_@j^&MK;`=fCDfR?3i zSpUVn`GS_ij)k-nDLwEN#m)H>+Cn5GF#{=0O|pKk zQ#+J^$v3Fdn=1Z^yo*9h2wdsTqKJEik2pBH((5OkXSg8^gd;g=U9%OPCL7iNDP?ap z^z%@2bQif>*Z%mEAX?w)Ht@R;QgYEQQK(KLH4kRqVkoo0#cAN3nwpTGc2?SCPJ7q6E$I(mcf7FHdE1 z(5GYlvXmJ}(cyrwOef)HA3ns%h=7}WR|uLkYuu_GCFn`{EoSVOm4kX`rt1y2P*e|a z?JXvQ656KO8+NTWqX>29{Ttd$XfZ|w3w|wL9GVfEDIsV@-s(5B$xSCbf1g)UK})_E zEi~VHP+evZzSDP;E$K?yb{pbA$3y|)Ve*d;3U(=3VIrpjSH4MVU!l0n=z4)omKfYWWYu?e=v zXG_;RA@&0%PO$zyT_ZD!m{DD`HM2{yM zcW8g!phfG1&?@{fSV9B7iGJ_UM_IhJqL$9mrS3FSbU*+|!Hua4(FdsC(QMCRK!F|MyDxP_xq?{!x zcVDf1G%RRt44Z%6sY$Hs`^(&+Z751Zj84$|*vuZJdyzY{BdxQw|BLVBD~Z>FP8^}d zNahhFEI?atXlajqL%TrQK)(A0ZJoNh8(QujEoqzBC$xAy9uGrXE@*M1`K~V&=Kp-s;DEGEnrUF$K9tQ0WtJjJ&*iW2J8&(?HuAI;)2Ea{UsYUY$x z6TGnXf0@^`XbWYOCbT80-1++D$!Ahc{mqk_{sHv3*PvjSzU;JoDOu+z)vMfQ$PT~;{vaw{E^kw5o;b%NJ1E}io!k`` zj?Kk?tdYe7)`v4%@p}ZVu3vz*2wEk#a(;@zXR<<1M4nq^6=-kdrwJ*tX_|Mh$bjRf`*JciOR~X$C z5saBeIL}>_B6;RdRfoFa+E26ag@nFsc!|pJ`YKrb1P|rs4x15|%i%|-rnm#~1pQEQ zEF4mlt;9cuUdCd&|8(b(0?`@N^YW*2=ybV&Lg;iB4I4)w)=n~moQ>z=P)U4>7KET@ zQSyp}Ma_{9H?+B20XUiO9pc-LF`*rX);eGx!+%3NZfGI$adhJi?a+1MZ)mM9_u??L z%%>E;HlS_U_6cm}@QZ!a9Pa{~GL`a*a8j41OVcYdkZoFh8BPSAJ8_K_cTF^SwA*SK-(^8+0O}Re`0ah@2a9q&~k!EuQE`w5vDdY`{wFo z3WG`^X#TeF0e}&v5k@`A=$RflPVqnS2#|DBse`OvTF&Z?p|fO*_%o{D>2W2wRN zCwcN-b#c*VgT@AwR|}+q4da_9s6`xco~Y^LV|?$p-o&kQcQ*8j^Q3&~4!b=u*{>Grww~-3J;jXqI>` zMS4sKhs7%wjlUcSkE<77N6Z>eaEqb|lp(tSbnu)v7dJaPOiDeP8Nl^Hmr&9aj8!%`$_>TM`FTN0s_QJf=!>!HXl1e&Z5Ya(U&ka1`}DCRLb<(iiv%t9 zP(TYsBcT0_m*F8jN$1}B1}(4Ig7(VtNj7YSlVpiWi+auFZE>Jc9IJZOan?DHgiNFp zmL+4 zDZ=QOiz9Z^qtC^`^3dEkUiJoGOHBZF9o?(uH(R=V1SL1k*Te97FHZwnHu%DzRK-JA zLoNhbHfGZxRj)XpbV7UCgyl+$QbD^Yb6E36KnruRlh7(;)@fCOHec^u8*;p14}-IM zK>Nj9zzJ<0hW25r<2pkac^Sv9E@(}NQ0*aT<)uBWy2H}NZ^^e_LgT7}z)2iiybc!! zM6!o~`L{!$*`vf#cx2uNrrZHW-HqBiHzU+lX@1m087af$dCmyqsZMprFiv~%Iv65! zah-6?Z)|;MyhA6hJV8iwR2EBF$iyU(W&C&6xB~iMY)oty#xMFpHbr>SV}JYQtmwF2 z9|+5cSEj4J5A2^!_|1eXjNh;gft0gz!`@K?dU4Qn?<;Xgv`W=?-Rg6?mf!{L;@efH zr?mqj1#L28(9q_9R_ zc1oy_Y(PR2lJt6jJ$PP8uRjZmG?*pwSOMb$bh6laUPBCb-oX(3BF35$>L;HzIqOnB z9~)QinbdxS+a$dBVCAsdbVa8tzA-crP064hGg(zzWx3UDF7Yzm8(+&QC$u)6@Q#Cb z1FbDO)gx7lcHjs!2cK1`AtHL@o!vsH|A#aViT zb{p(`3EKSvopV5T=E4qfxWFigSOZ#w0ga*?_R)9sE&ta3-SNR`+eZ*#OBp)~Y7Fd$dmG zi^hsoEaE%`lpH!;2X9k5wqMYe3)(yvTbJjKprzbzXh=lrAfau_2;feXosdxM`*T5? zK%FDBl?I#UC5ckpIvci$NHxW_CD?m*C{a{t{tjp zF}=^QQ9cF=HF`VhP{w9WZAdDfA|w)W#M%1?1jp*dG5TbYqgCNJ;GgP51hXYGE5YTq z=4oXcb8(!w>Lps)Dkze-2^w~bMLeb()j8h>sYkf~c3Xd9FU5>Q)`^$HRD6v8m(-M) zi-U!MD4ot}++-FB-~sLGSc(3=IKtQi(24?$pMBlX0vSPD6lYbHA9z8FUN)k&tZ1b@ zP%1f1Xp^87d!4_C@7=XHQoocmAJ94|{%vu9v!s#`%d+m4XO-y(PQQ;hkRB;fCdsOV zrkS7xC2-rMcrW~ajNu8<2|%A88w5Pf#&<2BIT2UeZl5hR@-WZyrwej<_~B| zuAo(n?gRmC2kC%4m=9<-XnwF=;<^rx*`(gu4Q=^^mV6?{*^phePAFNvWh zXydeB%MC3O2jUN}J3~kmMIr-S8Cg@_M?Z*#dVeUkA+pF4cnu|*=<*vqIueS^M1Es7^cFa+F1kVPn@dIwGU2B?^hS)uZL-r3Agud>4hnebGj zg!ZPVx~))a{)cJG>o0BpiD6o(S2Sr)YI!eA8&uUC!yt%&PV9l)Ehe<72wKlpVwb$2 z9fEc=LCa8(f$d($vr2$DuRqzH``&fBSab zrcS2I(n&sg2p=vMYnNpI-1K%x(~O46Afz12I8BSAI7Ft-Nm-|<%WtVYh3*W=KkGk?8~39X7N9c?kEzC0+Q1EXa}*U%bzqk zq*=V!fz-~l*!~rM)i&?{7ibIVs0(kVZf_4)On^2qO;gYoL2H$tE_K(u|ALnPul)sW z`B!MyazWcZpk@1J9XGUz!STa%*LdDo&#OLY_UHr+gm#-Qta<@4!e*(_=vLT0#Cr;f zZ7!ARww|TA;nyzu1AbszXAw5)rkc7-{=O>agW0@D5Hv58cekAE_{DkHx7$GWjB09O z%6XvsM0arok2;=P2u7T11Ks7V=w>0i57R-2RH3CYW9S&JvP0}X7l)^O!y-j2j$~~G z=`wZk3j2T-njGdxuyRiIf>vuM!el43h=V~jDmK7Vk&>IdGiP29V*sdNU-AWQ^kD>T zQTDv)Q8Zhg&=xc_3a`h&@v$m|QqVf)qH3|AUxIU+LA9w`0yG{|Qy%twaWe0eC$F^p z&vby9%oHf$pi?&@P?HK%^3Ixx>O1iq8*dV-TaD+<^8F zw9+(}=lRvFYY?=UOVjo$D+308LNBq^W-BU#H@TugMXpsrlTY^``Wh%TI-}Tv+pA`Z zB=+MwTzKzfHIAL@G2|B&-@t47PC;z2qXorV4}00Th9Kb(lLMT=HeZ`oZQ^s#`VNBw zW{Q;a%TcI6=ZV?@*ZD|lf`-@0n4@dkLGCV@y4Vn-@?rxH3u7dWa*HJ!e_< zF*cW!tOqmezwV=<$yc_^)3z(yDH+$x`PpXnW1&vUXF0!h z9gGArINPib9V4hAPgDT76Tsd>^#uIh6>NAxd%i=f(2~G%!-+Pbby7w^iw?+nL0bTA z%Qv*mGvGFzp60?zgtn=hazm>fsXF?S(B`_+2bNEbMs7L0hz2EnxB%D5p4Fgj1-(8V zeGS=MMZlfb7m0elRprWllL9W|VlKbusw4qkied+QkV_z)30qyU53dsb+0!j9Q@GK` z8TZ0aVx2*X{Yjfop7;@ld&Jf0CqY9_73>4~yxQCoMM8(9zVRnFHR$QvaeEm0n-Tab1y(JS`X=E*FM+Pq|)5;~aU}DuRNIg)W<)(DobJ zB50q%16+XfxS=K2Dxj@5v|$j8(~h~wY)0%_JxoguXkUx$NMoaDtDKQ;Xrso90xrE? zf;LY&>IH4=vM8T^#Mu+H-LyG;DOq-!a$Uz|fntctp587Q0hL4cJHmAQ#eBVGx0dZFVWhKqF74%qVRROD!h?jAb+ zS*9a$`*}M1dS5L%EC=3w z@h)U(OsbCkEMvVFBkHB@M#~kiEyu5o#-W0ht=b1woi?Pr;(RGB7}s2ZN z^XSOmY%Fjz8#K+5hH(|4kGkUan0D%L^?Z5z(2#ogJb@3 z-88{sP+`ZFITuH{9F0}Eu&u!6QRZFdhPJ!KVQ33OBHy9Kl9}&anm2sR_v|AcmPhnA!>@kJIx`+tq4f4`xn8FHsxX?ePA{ni;gvIyj}S7(~d z`6WZEN0SFb*Svz-Qk3T#_Am_%9~x~`l6+`!(bW(q%8No^Dtv2SDT~|?tz!|Qk7>vp zR~fXIt9*ZAaXhP_Kmc5OV6bl^CUs1-V$kd4-v7YaANzmg>4J0)8<~pL-b_lLT`cgU zSwUiL4;=~e`oQWMmZDj2OY})p#`e#9I~LaO16g_4zE*HIX;u0E3tC5~J!BXmXp2^x zUF*sPEga#O>Lee{LEoW04;}|N(@64}Hz_5eCkM^%56!;Oj*BY^!r}xi27kbBS)BL* z?l^XIbj1#aV*tCM&R~cV%CT5N?7L1wYRNBMU}^`h$ANUv>64Y?Kf`QZJ)Eg z1q`^ls^=7LJYB~43jAwmwLwbHAYKgc8m=5gZ2M>n9gp}Hc zKaKGPEo$?Uxtqc|5YY0y-9%naM=VW3TV)#4d{0Hi00Ou7B40%Y8?-E|lMFIeu?EU6 zRW50b(Ac6agz4vTPnVh#Uk(lzbhMHHLcS{D;;-M}$__8qT(qt`BtUm3~JG~4; zolJ_K7bPL^+k&eiz|yLR%)Z<$|_MXi+m0+A%Np_LrFk z4%ZRQoshcpdNGW6{BMFb6WY_zGMnaxRtY&6Xk5_p35K^z4#KOn!fBPbWH24W8p5I5 z!Ddb2d;)aTj_xOr5zuNMzoDcn*)Ptvh3#UhlU=Urkd!%>BAZi32tIM=OofEK&GLH& zF6Bx5o`tR5X$~Dvye@6>Bhlh$TpZPhk)Wk`K`IPd?DEjk;xJohq&H}vp}v4OOO@&7 z%&C$Rup|9Gz`s$x+mY_cHu+)Vndon`*Bx@xKx3N(%ROV{h>yzOkgl_ z8Ye`{h_;U(d~hL`3^CpB1}RF}oFY}_z=`vBqk$iJXLy&JOimsT7ryZX?U0+o55B3L zS02gqWp_|nI9J*UNLuKzmo~U8q&8juw<^J_$05(iNP!9muS_F#nbs$1eTSCB;`M^I z8QN-S#|p&<>?Y8QNqPR{#B5MCyT*porRSOLH<1BX^^|`!3`$`<%m{ehe!vb#21% zZKrLat^hnm7Ji} zfykYP&=x~`vVVDKpTmZCVt0;DLukjJ(0<1!CbVG4%a56%ZlW+}USx1*PsqHy zVY>*rKXy62@&E#Nt6hA^G@}>r#J^Svo>>J9T9{{9R!fyOTk1paPjUjwJZ^L^bi4%e z8+TsN1Z@_yP1zCu4ccH8EzMU|wQg@{^F{Xd9zZL}3tGJwz8DzVjdE$cf$UFCXcbaz zI}N2EQltT%EiSejbEY{%)c1v6U=vRe4zMjvpK2Q?`qkDGs9W4z(PCt(Cu-GMGrXD= zwx;nR4uSB?8bi0j z#gPOhwlna>I0KPKu^o&h@=X+Fi{l?>)Wf$+S+->wAk4&pxj1GZ1wQ_B4EH$U!MxD+ zXy{~R;%l;6fzaX>(8dMrIp-b|T9$EycBQMb7ssHpYO5x4lAThTppC_musHI`olWe> zKcP+k3T<^(fmViewDd|Hbm6y;qudm*eJ;rY3!K9k$gn6VqPe{yiY?S-Nin#11ZeSJ zEBAiynuR!5?>k}TzR zg9On?OMd)dq0*WgMmjs>Upuzc*k__+?GZ)*h>H~J@P)R(7|I}-Fq8WY9V1o_v)<^3 z2>$ZMbDe@oB`di?5$gmO{Z*;r{~KB+Qqj5X1KI?RI*J0g-o@oSpiM~OzM+j3^&*Uh zb_m)+xgyAv7qseRt+rA9gmzG`XK14fMw^IFXtnc2n|mWM8&QoEe`nZ3%g{&&-ao25OxbZE0A(Nyl6>{|0>L`QG7A*-6lW_>N(7&t#Z zz4fd-1sHDtp-=p=j9kPd&ThnI0)h+4UB%UCD4xZ)XO?VX~$Q`^5n+%us?*SHzlXhG-p+{yLQK=p?9c|psO z=B}n!7$Qz+yP@60#T#*y4mm^v7zSZr$@6;sC(a6pB$td@{xOlE+9oZ&EC4Qb6Iim1evhGv4=R9q3GQ9`O zxaoCnG?t_Tg2XtGO>yOH^t+2}&m;kYdPa(_qpgj53S<7V%e7v6|MWye8(Rr>-gr6s z_Z&#=2v6djR^a5{m9{Q?quokh7EQrOACQgUze1~Xj>cBqf;w6hc6TN&L)9DFOlZqh z_Y8+H)=AK@p0|HMi@uoYiF9z#_~eE*8Cu8I0NPb9JzWjw#1dhZLF%wqbhqIZ$DJae z(f={|31Ak&L3wjxBfp#p_RlM zy(cwp1Z@+vR9NxoH?(YQx&}ml*`D2P-Yyifq>6&j)(hHVXa~z<-1U(d8>zVXSm$u_ zMSd>d;ZFHngHHA=vWbcY_80wSAxzgx^?c&Y$0yi+DPuMWNsq70KvF|T^d)tsoh7Q-9JgoF> zN?owP;-f-UfDB&7EwbksA7s~01lq@<6y@@}a}Y3vKG5mGrankjPpsJxm(hA$^yQ}E zd2Hhur47DRXxpL>b+mVA2Lp^v8xpkr2v4GbcB9eF1?>tNir#cUOGZ>wkH6>@ctiWb zr4)&?6|GJ{JK(2=D^Sb^qzu;OiF)k|T24#1G>4CXwuKoAO_OhE+ibK*V5fGgG&-Eu z?mn8vWJh(yy`y!r+ns!;@i)riguC~UEku_e*vzn_wE$KCUk_EyGF-~O^5kOvwDZuQ z#P95>^V2?L(33SXWR6R}l26vX&*@*6FR#c|s{$U->HNxU(?W&^qb>LZQioBbMaDBe zLE4NK%8G(ikL>#go-6lx)6L4>h&NstEk!oKWoG0)s?^By7t9pb%&xM#Hc7sez0cl$ zQ(`I%XQ~~2Omgp>;X?gACbXx2sFI_ioDo7hZfF@Sv;GY&ddy+))F-ryB67xZL7Tqb zpiO6)mTO~~*LbNTm1nLT*Tm*EvsE}3Q-YnJU>CzpE={gtOmJxu;>oDar`)3Nqq(y^ z!~hyHTpn_2(+SUey*(khvrlW)hxE8Q5jsU$%|Ezc%sgq?Ze%6uR(MJ>au^u^_*s~p zfY-V}j%`{-nYRCC`o)%VBo7yw*(iDr0=Vd^+TA%>C5D*(`WLiZz=BruF*$Pk20R=w z#krVi1NsF=;pr|e#AHy43swJywi{Y^^fYp4S%cMF&Y-QWdB*%Jk4nW~H!tFUa*i zd7D`<4aW}3`%$z~E!g}%EnCH~GB*1S%9E_N>Om9Y^KEgUd(D|ulHoO?ZL~Tte#LK`sTErp-v}yUaMac~ZKoGbEy6AsSH^gj z2USw~D=^v|vTbLzff&Qz_!#SI?+M5RF}RPtdxIBD{Q5=9aObJboroykZTpS0ueiu`tbH$6!L(z@C= z-JAi%712+AOmA{K^OO&tlwse!_~Ip|OB~_SIAAE(t2234<8!!H+TtLd`u8-0i8Exq zphd}W9)vbcXtxP1{akH4OTSn^n^lyxMdCa|t5`Kb+ihiY+|W{zwJRv&U!f&Et}()$ z(4qu3w22LpTXgVz-nV*I4_rT$)AQ4#g_CK9^39sA#Omxrc`1tp{DrOSlwxbx@$Tyz zhb~>tISioQ*S_5UO~k+Hmghl-8HI6Edb}-;BE`{lp6g5I+$YHniDaTh5*sg$bI422 zEPl=UN#sixvre@@o~Dd<=hlmZb6jd^7xd;9Esn;BK;84j7PZs-Z31{f8?(VQyEzkD z9I2CN^9C&ruJpDzN}kR@{l7x1pex*sE@->B&>XgXKwHN3-g$Ajf?qzNCE=%=;3%H3 zSx)J((-D}>8@Pi=GFYa#SmdkeZ-M_=8AAmoFt?A@OpPec;fV@jR|p0}xgBdGRPh-U zwZ~V*P(F*C)5ZQc+i#iN!f7o|!tgbrtKKR{tVL<)z+%sGfWjuX(4tdQ7Yt)mTdrw} zBS3H;Py~SF-KN9^4dsVBXnIi|oDG#qi!g-%@FjZCq=k5CCBNX39TD*i_*}O?)c>7HA(u$mwNEMnwhpzk_W2(^z@4V`VD?G zh>8V%M^1_L;hm5Xst#eriH~xNd=LskkoQygUumTs|884jaU7)4Ek&ONuKeu&Jn&VZ zL0=gCTf~K&`Wp;3NPdsEjx2r{b1c+~4W9hk=7Td9B{uCk78!MUB%a~Rf~!>gf<6s$ zpyt2*{2F<2j|is&?ZB>T+lLrsJua239bC1ZfNq3}I)exv$Po6xSSiDFwEBYuM7maTq%u|YlYTx`3Vb)PQ3 z%&^7Qw}_~?nlBK43=N3~r8by6#swj6k*&(xZ(8*UWl71%j(M_ghoOgTwLHREe0**& z(ZOw}kC|5?T3BtTbS5a)p1M*4sq?0kM>H8mSqFDsbYHL$;AXHi@^SJE+mXG=Y16Mv zyA8e~0qw)>N@?rp$TjWSQh9@x*S(}s<{Px+weoPgq1{kCrV`XJSYnQMgFM1jL_RCt2SqjIj{uOoXK{URgl{uHW*lo42 zD>bk7+@IBhQkU83_59L)%}nZm0hT*;3e34Ug7i}#3PoIq2H(;<@k%8I$xc$vB`ywj z9?{QwUmUZxlFKj6h+2AI9N-+6xj3-uaqsw893vKoy*{xx1P8us71+==($8A9U^lXL*A*)oXF+=$oUkKcU^z1#Q4*XvgFrR?Y&b z;aD`4w87jvv^cLsMO00e5d8I{Do=BZIs?y0=k^S;(|n0Tt)g}i9v@fCp|}qkemgIO zoMp*HqI$zLGC$(-PhTEJpW}Og7Y{8D;#7dmTGbBweJW%RZzXkOWbTax*g52f4Sr-6Gxk9ODz(_699rh0``lLTnX;mb*QxVqC@r?IMp8 z4W;*I4AVHyNjq4CS$hl2BeCU@Yem1j=-0&G48mT8qDy0nL-luRx{6YmiYz=6Qbn6P z3JIb^{&YP#k2HTjm#SM|+nSc=o)12mTcKlpWhx)-DP2NI{!#Xi1yEy@+cri4Bz`W&ZYRtqek@Pu}p& z3cdwZokBs&^DD`&7tl7!02=A$l$AWmuMGYpa;wU8r!T(Nq_)fomQ&hj%PcHrVzi_C z5}Ywzz9HL5X+hNeNHESt&VLEbg`51^Z7=W7|?r7oFp)2`?Pk?4LE=bcKpkhE{ z3tPT>FnSzv&`LDk>lbe#X>_F){J0iJlU4OhGx8JAL_EWySOciWkjH7NTjcv_^62_- zsu$jMPRBC&G2NvWE<)g7f=`KJ?4=(0&?LU!i=%pR;H`YPxcCx_=j9D4Ir6>8D{Dyn zOPPm@`sGlMwK+X0O#|)Dg94epY;blR5lef6cKd)f5!#i|qHbsRw$PZu(5Ank_2O6= zH)dVx{J<01_@>yiN*~ZpM-6sz{uNqybH;!XwH&V74pzgq@xY54@^9vGgv1=TWmP0! z00#2^$Aj-P_qPsx|Kq^a6%kL6bc?CMfq85)ba)t|=*ORjlsLqOhl?>)R30^+n}U_z6=l5U=g;T~m&#rU)!< z=3)U&tCA$a@Z#jQ=|YG6kYH5mznQe5y>GQ74RzL#rva@%;_CMuP=M1%3I>!O6WUIJ zXB0;Ja|qhPM#K#*O}!q)F_o1}yi?FJ;^|4k4ODM{HVEwdba;4!whlqt1ud!cuqj?Y zpiQ69hQq(STt1V4SFi|inUz}gPqAQWzXwwqP?76EVw;yy3VR^mGpHtdU3>F@S{^J zlLv*3e&083%dBD&qdV;WI}Ocgjo#)##NM>F#mxLXZtG8&F_1JwUzZ=wGnd2&iBR5D z{b-ZXN>?wM&5|KXMjsQ}@(C>p(qsEqXoan{Qx~*_4~n8-c*ZMe>nF6CSCfODa3!nb zU6|BaOS7SlqKK2Ag`{aaxS8}cp_OFtGM(4Zw9JT|^SjvBfE#C4cCXtE+lupfxuoet z_LV(R(DB}MvAH_A)#V-63l>L{?o0RAHg&>kI3?%0=@;tisuQ0_ZJuWlr|=Z3e_P*9 zfxLz~cZ$vY1yqjvq#3gNSA4*%DQ2X7vY#`heN=}K&9pwg zupiK}d;VQ7XiGA*{eqTeww$G_m;VWEe}i`X2`%RUf|jniV&YGhi4zk4gtiM>8726p zEKkbSyj0ScIP0!Y62%I<)~cvLT?t&!tYf%0(63dT^&2$|XtYM-v&&7bzhydDY3w-EKBLzs8?Yp?6Qe`fPVmax|&)dK4jIyns(rk=G zgQ%)#oJo=imnLQka<06&(!sgrK?45&aq}CN%`u*MQ5z-yOO|(t$Wheyv@MB5zN$Dq zhM{%R=Qo{yV95s&YpPCVB(xjbSc105oy*Y9Z16#|2W2a~LEESHfZaz-hjYCQDlTY? zp&f!Y8QP}UIY}{^re0hbF~NrrJ?4KW|F~XhPAH=Pp1C`4+JyWT+}BUWgD-F!E?|FG z_(8`D0U?O&fEy^`RTdl4@-fFrltxmQ5rYUl7LI2WkPxuoZ~6xf6nJJ?G>lmuq65w+ zS6Z+leuq8XA=jK20I-xD_bA}eA+mf#-huhE&L0e0n5^xS@itaw~7Q;FUytsh&B>h2N zTN;pIWyhiUs`xPdYaPT7)jCnlQ9#hPfvhH!DKR_8o^Hh89vlLd2m) zQr2t{v=}Tr*muvg%e>40(NOxS)+Y&CPRJFmjV-$UF6qsse%SJP+|UxA2`z*$i-T&r z`aA5#im|WCl9m8fp}eUnBa*`juyW|5m`!xgdV+Kd3R!nIx$JmxbSYQK>05jOptdHJ z*-v2NMr4rxea2DPM7Yv+f4D!VZhCaLa;7-zA_i>B%-2HDX zfH+)QT2Z#@TpYs*^BmMQjl%iaG-|w*_eEA7=$0uN;2qjAv9+}!CdteQrvuk?Iv2E( zS4<6oIe}ASpG5o+^G~D-k}t^zZ1aun)??1|;)ZtI(DwfZZPE<4l|>yYnQenK#W)Cj zzLkqZ-rFx1;bSI!6^2eRzKdMjtN?@OunyYU$)s@%+R#*5wPAkCN8Bxy2Ky2Xfm7y# ztB3#`GMG&5Aqn2K=P7B+SCQZ)-npGj6er9F*OBhd;3_W4TwUS1+50!Ty*M(dKP
J#R}OrH}B~(nA8M^f3;df)>)$+!5{%LisRgI&j+6rtBE6shBT>6>6ZUW zE8o!3_E+wV7W|Lzujog>A7P6GPWUcVazWA){QSawe*r~wHUQ(RemTH6ArGMCf7FHO zG!aA=PS^^qv@rNyK{x}nJY+WNE+V8xVM}<+Fsm^~2`Bccm7c$}K32urum*=v1=rak zsRR1>nS!tJ6s+*z9Uzw=r;z$JTfkQ2hyQXogqJ>In*g4N!_$R3oWhnf#|ZKe#5 zr31z7VYMOIo-v~I==$2~Y!eUe`nq78x`+5C}BSz2WHo7=Fh zlD+O|dZT_J8V{=NW51UJ6%ZsgqHW#j>wsZdJ#Whq{w_k&}Ii# z;BpUWv!VTketwlTCzC|Sn1M}bXt2aLi39qBm_aaF#liDIw_IZ~0N>*{oED@DEDC(4 zzZ1@k--@?db$}zcnm4Gyxah9=!!c%d+_E%xts6=LJixb7PtYBx5;X4zZ?#kuTnawl-2Au zj05{*eZ`lGPm#pM_>DGM?~1k}K@*+P>bTitE>Ti&ecL9qQrdP{@Zz%%LCXNhKsUc; zc)aMaJ67nfBg*2J{g#QFK3Jwj(b!5LmWNV95GL2gx1h~2oS;DW4`|os z?70c;n9vSGo6K#Zb~TO5kbPcad1H>t1Xiy^*vc&(9#IZDATW!TTs26UhsP}Iv}x-~ z=RR>pa`)g^a7x_EWtD%A9u@7Kbt-T$jr z)H}u`tuSOK}shW2u8v-R_1hu9qqTXP=?sn>OwMMaKXnl+VPiJXSZAZao zBje(NwtYbBa_K>6tD%))2#I3DO-{aRND~{}!v2O9*j7PXZfNg_`ahw?;rj+HO3t`P zXG05Sg_W+uksWO8JJIHPf-WHv8hXo6e@7#9ItQw7EOJTg3;DBfktrAREIGQFH?+8o z^1JO9#n=2X-)H`Mg5mp#ER%UrlZ_4%$ToXB_zCJ9jDl2QLTk?5W9-kxkzlZ>Qdxm+ z_#3`_=rT`m*v%u&2nEklW^15(JOY-%s&)yK)hztBE}LPT-iF_VEU76|`B$q*Z#Cml=xk|Za>*P;GX)Uo+69Pfci%PqnNqsBGj-;+vxmJS#f*aLGd|@Bi~WPM zfrA!C_<9Q>jpQ=sIQQg@4uWFF*G0Am?vF8m!7Kzv2Nfi|e{zn*R$Tf5buM$64l)D25;H7_;P1apzqM8tkeX#@eY}ice*H= zS5-8HDU%(5Qx9a;O%&6(Yb@59Bp%JXw+@By>S&e|G&RA&F;s4X-dv~?KAeLVSc6Hg+p_gpV>>Y4jr_$ZzXbc>x?PWMHR#8QNrL^$D#BeAhIXGtzWJYj-V_ zFxwlnbGBg8C{IRExwcc| zZ}JEud2w)x!2&-PUd&N8*QT;CG@3@;9>E*7IneePYQ(YRvMF*2Uea)SXy<^dyk zTl3uYI;LEt9&gEnpWs40)g3;(qm|sH)ws~y`XI>Qj(&g z)aF_dXG@D=cKxvztiG*bVt`GZ>O7Q8==jH+VT}XvID`&OCL5cjcs`~Km3=|8FRRSa z?hw7%CM%hZlcN`Ng9m~tumPjv`lW2BQ;YhWcaKW%Kbrdl8zw&MjzRS)Yq_&1DBvgOjReKFw z4k6jpvDEZeSRy9&{Z3I-lZOa%FVG@D%T$^79;VOiRNmaS$;a)T0TP2zk9K&q>RRPB zx7!RtCN|ErCvBiiXerZR-SJuIJ1y+tWjV_j+L08f$AFa!+VTc1Z7i_OW&OIpp&f#j zP14=aE~JR6?)ab3c8kCmIfS{`4Q-f%Xg_VPtuAPz0IJ!c&V5SWJ155RxlfF}9kZ&~ zT0R;oUnWoayHDyBl5ivvTU-kkI)jMDAk$olCA$W{9PFoAB&c^J_jsHN3SgZ!JB{AQ zOL=c;j5%ko^rzyt;(>Ivk{-iMXLGWXY1c%w@Rlj+Pdcz|)3Qixam{s##t=h^O!#k$ zb3auOEIqw5!&Oo&qA;ee0z}Y~xo2o)h`i7P__lej$wBr-n{s}FJXsB0d^ADLOS7^h=Pm_;APQ=cxZWP`*aW5mr zj0`HW*;Gg4Mfn!*p`GVXcbmnPwFFBJ&fk1_k9K5|>Lp;WTtOSN~+DqH(~=5k;>0uP*c^){Vcgti-6p692a%@f-FhW7gn+Wx*KyA-FSPA|C(wKNz$1phVG1_2lVwwlp1P!45|cAA1$`-*jUa;ihXM@y#^v_$xa< zAMYDGjty}jL4e6x$Xm3lf9q;-u8h5lUm_xP_aG|{@KY}8LCvaP_GXJq*h}G@Vb$A6 zIiw3jeLfxAP}K2{bf8^V&|6g;E5F{^%c#*O6V^O+nhb)!n<= zQq6O5=1{~?%5rctHR*|%>B#V7t7R0lg({rsLc>3c@shL{s>$s-QfS$xhUiNxVT#%o zjQ}%2h)idVSok|*r#szYrbyQIGJ3UV8~BD6RYXo>LR+40sPh;>5#ZZA1|ac9?w9M3 z@_5;jhiVEOO&aikS|n)81#L65)Z>8kgU2O#0nW&XSthh@{SsQRr7=IOmVT|eAUM}u zg#~$LfV$>BpWwPaOUF^AM1;#|a}6{TAdYLQU#yzbQh&JN@uLpSb+Rr)SA zj^&`A%9L*G`{j|tRo@s@SFKIUPVTZ} z+U4ZieOLy2)hy1N9IyWy9^1rc8M`_ayR5crUf{6iz*A@L8S}FzF1#OXW%nY|> z!-`9ri(^8|+VO(6sNFE3EwZ{uYHg4ZeM5`B)UN8|9ok}OMG?>lpZ;QLx8cyh&CSx8QU0cv7!}Y*msqz?9R1gJ8UJZTRc!9I!%EJhHgpMSLuW{-M^d zc3nbIsgxy-yrQ+(O$b&#v|9rXy5S^J{K?L|J^0zHK~ZI3!N?`p3^S;8r`is#t)}bD zwuA&lx^j{Th%HO)57p9A9Lo?N4R*836ac4&)&=mwWV(54I8l5S{CvlkiW4ccdQkoZFGN>>~}Y9G+D98}e61_(+vk|5ct zNF&YhOofpPG7CtLhIeOe6l};@faNPa8JNQ};PUgT?c(Mmp}Eitn7X|ugz@z8B08{B z#l;g=|M9CKfZI&dgK$V`^5dV9|8Hjvq&Q14_aVlF-rWj_C7Mj@bN^2q8X4>eRA?b5 zupiTDGK0LA6B-tLnv9B`$9G(5cujoCAQuvy%5R2-2)yb*pa;_szJhL)0-#Xn@4io= zae(A80ubxMk$LDK;f)rwX5husM^$%08}mST4k)G1(Ei~3K;D9& z*oJv3qR5jlL0euhHJZ>4GlRK_?SwYK`ai53Lc0jsFz2Gm1vRvM2-!KRm-UH8h@z!$ zRD)T*ALGDQ#c2no^rSv)~%rR0846|b)(E{zZnO*b> zVt0EeEV83^ZD`HuMaDbQ?9PJq7Gt?8az*hRoC?J5AtO5o8^$hVf=v%u3WIp^SIRw7 zn|A&d|3J;g;Wl5k%Abd;g5nwY4O#^Tgg@tp=~ss$4PiYyO84~8+GPH2iK^Q<-Bhn(9)r=@$xp$ z*6Pw>4k2^`(e~P&?HvEJ^}Jr_U5mq(U8Ggg9ezFm-S#oPmjRkAlXLeIpt&$b@O3OU zjdnT@dNEM-Q3ggb7n8TuimT-kV~)uRolWF^b&|X|_}!2qD8gL3%mg?00YnD$wRrOM zp$_3`#c1y0#o@>%wU}pH9(ouRq-4V1(5@5O^e42N<&N*rc3XjN+ttxgZXKY-#kMh5 z_q1jaEn~{TwSCL~U@nd{{k*7{aQuc-u@KY|zvsK~PNTN162268+{c$EMNOyG2II{5 zkH4JT{d_*r#Lk&v3EY8yBg4+=mztK~bpibmy?0&8!_ zC_bKL)uB!w9PF8inY^mcS-!|Z6zA|t+koVGBQIr=NIs>7#ERLR=KGM&l}GCfjc@fB zi;S{xMmF-vnGP|ELvByUTn^1vz!hNIRMxnqUw*4N+v3=x+o4Sc@%1vut-eEBV0yzp zjS?GQ!3Av=w8hX`qE4S;rp)XZV|d{xl2YYpYd5s@hBm)J+iz$!6FBAKdqYc_m!ZY} zgaq87fGWnUk!(UCxnp8P0-=pp#TB0RflDmahsc71L*_2qq(vrv$sXwJg)9HI=sOa> zHNcl+@cL@d#7RBObqL^j)z7{5)nd<`~|shiB<9I{J2E z9YKSn(2SHSY7i{-3Zk(4l+jL#mdCMZRl0dfudp;v8b3YHc#}#k;Lp1D_`3g!EQQtD^t{T8T5mgnyo&a>@K%qN+uSbS^67y zg&I_({&JMdq4D$sB3}y*J1ir0NVY3cIhmr>J)Ce%UNTFEp=no_e6rgV9P7#?>W#sE zSi>2&B48xn*7&O^0D_j(#eaj=tdVKA@FTJn-|Ve-X*e2Lp@z0hXc>K5l)96|nKHEH zf;QdIj$&xLpp|92Hbj<5Z_rK$Kyl;v1p94WMz;trqUidr8#QYe34G9QtSFMQh%}*4 zOgc`@gk0HM(TV`Wx;~W;7txUqfS~JZaTGS1uf?$^$xH09#B!?-Ip1?}boz#p-9xc) zFQn1y_a8DqY|Au8K6;tv1@M#P-4#%%uElp^Cf_=I{Tny`GZ^SGn`@-$ zDP-wh98>paXc?buXlt1vS%j9FwMha$4ei|at8x_tZR;1boN&?}n`&AGKK$-~LAwiD zUAPsH(I>P?>Wmv&Txm5YROjMR>~w<&Jw{lfLWF{!>8V*gL|0J~-C6}OXw)47Gg`|% zcm;ym>LJtY^8_?6W_7JF1j-68ioWxMS86x{71?xFx%PvOmS%lvZAeTc zW@a*I|4F8lFqBn`ln!zHekpLWtA0Piy9YrGFq8m~G|#Z5%tRFOhuK2sM2cg2vbrhx zMCffVQ53Hhn;g|MXk~+9YVh z&J||n@qtlRUeIb<*O07c&0}Wa|L@Q;*9d*EW3sZ|p&i{)tY7NCRng`S%0m{2CVvJu z=S(YPeywMvIjZly==V_Ut=K-vp7rw8!-GqN7RcyZ@*7wJ^P0o$p(t{zl7K62Z%vLl z=OBqWKXrO&%Ml)?APyO=4l@5?%PLNMP%6Ob<=G*Qr+n@khxE1-R8*}g$bmH1N%Et!Tm z9^K?LHVXD@67A%nm>ohvxsch(>6J<#OJZAfk>gpWC*sT9jFw4KsoB0;P|i#>o!?)4 zu!m{|vk#W(XMOqSstxVbx;chyn_4dz7ouAzrT1tWh>w0z=Z5WHbaoUoAmk%aW)@m4 zPTu2X5blhUg(ZkVq_OBQh)ysiy%)!@F6|pxwxD~|i!W$s}Dn~vu7o=0ZeB= zwV@>%9Lv;tL0kSew0)k|v}Alty3)`uyFlz59va#@OS4%MPBOk`0J7TS6YSi~IqKB- zIeud0$SBybcz|V^_H@Z8@O4xfZl#x}7i5gv50UR|X7IHm1DG`*4Hr^Ut|v$~ADN4z z$nFudu>%4n0e>ersyFOZzp`u!a?VOlNQyCxyFmR~p=AgQc=K8CpMcc2NuKxOP);aK zIQy{SOpKE`aEr#%<85(>EnSkEEvx$^`e-32;%rF+G~b6NwA@6~lv;LYD*)Q2Yx@mt z5ww+;dqYdcxR?43EfR=S>X5CF3~jp>N3YJ4U=iU(fx_htT6bE??3P!zR)lj!2*?o+ zOfrwk!j0tT&ZaVMxeqwzL{;S!p5sY7QWSvwe7x!^S~LEp2g|Srt8q}QVhc+!K>#rw z&o3vpi83vtaX>=R$ax3@WwN9W47uSU13RAZgTc7A!&M}L>oevJ7|5TBq|TC zuMcQxvQQa0Gog*{N6-l_XcvqbKu6rqT5f2g4A1OPD54TBQ8-2_tuB`8o0eu0xTRr5 zeUbA~zahgwam0RXoP<&3#{Yvm)}pNpBnfB%G8i;06{Y9PEN1sp>Mh9mO0q*F^29Op z*^@llS9b>{=+Je#Ve?O&*W!v#991_fIFbs_$F3@c5tYyzpC~9LS5vkg7VXmx@Iz$l3D3E{ig?w6)wh!mLIi7e?iUsQZ!`!aLm$Q_v zVE5_r8+q+bZ@8*zP0HZB^mMr1SZ5G~X1+yT?L{pR98Qg9JdK{ISv|Ei76%+o*|=bA zoJtbxNEft4(V?u3v47%Eo%CPfn^{Rj*Sj0gJ_T(Ow7f{=8`@-Lup?>+s?|XW>-I$N7q4J;*v%%EQ5!!$kS?F-6}colbp71rb%p^oWzG2QYyu{ZIFlf# zB8*XK1aTs~8xx~bu#a*sm2DpOAQNoG_$D^VmuMnWGm8i0H9;4c4Wn^*XsV}|Y?4fI z7}rsL?eeyNNp{ETb<<24$?~?d*k!oF4KE+`H08eZkg9RLpvA%YT7U1a{9JcJs~G2^ zhF=l1B$fnc@b?YvFtp_pTC$mbu=QWi!nLy-+HylXRza)$4SZxZkZx%CsiA;nGgr_q zfR^1O3i%sw$9=?CFpY9#|9i@V3c0wCGQ;BST2I60b(BfV;{GUqIHpKq$~1;=Ww1d{ zvXqApYtl+}^PB>8hSPUf%vpM5>8_qv>>%AgGfj&SZ*qAbli-!;FpoE>sacN>`1E^G zOCMR1RNIfVc+3&SDK1R2r}&u8`PY>K9r`t0ap1levc1R5bb1OSD{3q%WblV~Lfa;^ z-O#??q19G~4$woM2g%u8RWh`7O3q{o^#<)|{|0R#E3}*H{{}5m7pudIZ)nM7evS*; z^$ptOYqR49(FV+OabSU43a`aMIey8yNOHH9U8#tR-G`pqY)ww`N{Jbh^{FWl--K0H zs!jg6$y0TzDD1LI4qr4eD_7lBkNBteKeV@ zNh00eKVlJwpNuB&#Z#WyG`Nxo5`BX8tKy;A<4|r$nO>UTZ_uKuBW9IAP$BNUh%X*~ znV}t;HcQg`C$v^)+6z#N!%F_7d4HdI-J-$Q8`>pL-|Atv0y~LERa6Zv7RxDOY?j|q z!>>&?<%!=H51KU|ugFd3ZH?3~y23+f(ZF;|J1wSP3fo&WXKDY)bnBr|Vi{S;UFsp` zsWh-Nt%z?pBmF4iGwoRiHXPlH%Q`&eH+Sqv<6^}Rrq2`Nx8KYJlSQ+~23;2Vyz2+! zk7idzf!km;s=|%Wn2=}Bst``IE@5HXl4P}xhUp7z>e%&QQ7Sb#zZ^_i)M2)WMPTV3(A;ga?gkj1X|E{&FJWq&HYSqB1ny9lF(&dN=+~1_=RS;mAuF}@u}RuC}V`w$K&cYKO8uB5u&VoiQ zt;xz%+HBA&rAIQ5V4Ng25>s?dIZKASz~0srffz!|xX;xvb2GV=`pZP>b)1G|QW~fn zQL^-UVw4d0uOh!%RP z<5-j76ZTz@!fDE72{2_-#e3G;PpGjo$Hit}e_;jweH^+=FE_1B$B_x$ZaX-S zEmTt{>j(^;&4MMaefcG*;r4hp^mnJ+wA8+vhz|yK4}B(J3Gpo-_7>R%dP9IWD)+Op zkGX%|xM(wteJ38BE+;oY;z29h>1fnFawaqb{4D}r^l3p%#hctvN=+) zTN_ULHC6wMmn89Q^kJ1nak|gd?kc9pUcu31NT~(27A92(tN|US+U$YBR^KX zGgS%drSESUS_zG3w`FUn&^AeEvmvw%?O+?#lL~DULVK3+=^4;HzO#F zmY7&e@hF?QrG{HWYS)^{Nqz==+eBD?7XO5bEbPPg_GC4{zi52h)KQxEM_Uy`HMI|read(c!v$eLt`x(=Qw?lhh;l)hW9 z<*_hxY2PNQ=nJJ#H$!M^%7h(+wqj@}PQR>)pK>H@qrcLP1zn2iR3C`$s<9`0Hmw~U zIy3|v$lzR1g=xuA#aA%X9j@;~u_#yhqYQo{XHp8N(JtO!0fDR;6(cEhCcRj5CqYd} zTQN>u!lp&`Ev^FUcEaind>b;?LwH}-5ljxB;;6iA*kHg4+OosXeN>5yx!)ta_DUrO z=U1~ZSOF1Q*HooDEpss_mO*J~n;2R!R~1^4Z53Joy}v%RB_&qtWs`(` znULc~2(ABo7oN3v7U&fWxFXBx5ZVfQhBN79<8k1f=aX-im8OX^BM2JvcijB*Mf`zk zY11ue1|mj0_quZ}`lcecv$*oxdoG!s=^5$u$F;6%EaNLzwba;#yIawilpu?#t3_B* zH$j=MVu#rJhCmBDZ01xk)(F0IlQa@)7B&euqxv6dvd8?W${F@17%;(@A(L63wbmuP z;-}h1m6XtsD?t!Uvs&V1Nsm*8o1%a;(YDLazWccjmpR5gcVQe)A_QLkGKQ8F&Flp0 z8ymZTGXQw!f^_k7hPL+5me)hew}v6B-8n;w@C>bm>s+!Oq>jbVx2UC(bu*w>_<1R3sS<1-GvTXUEyHnO)89>`&(AmP|60}5$!9>Ah< zeKEoiizVyQE--ijYr!#;xJmJy?vhPEk@Bi^8(~;fsSPN7Gh6%kO|`izHW^ytF-lP(;^MIspO)e;HAxnf@Tp}!&_v@F(@a77O{b!< zv(mh{(9|It?l&+5r%f=~qbw8ZnB!$63`9Pe8-;6(FE>?YH)oq%h*$9=Nm#5ihs}kC za87HSI$-;K&5oI}Rhup`kGW1*yAM)*m55QDPBSIg^1vdklB?F;005K@PiG+r!M>`iRXx3o(p`BVoSVFOSI+E z?SzhXu;>CF42z^pBM5#SagTz^-gO!;i(sy*Y7N7N=ffJ*i7UQhO05STIuii<1l-5{ zG7DHzn5MZ7)roUeTxW?Hud)Yk|DvSkyqk#Y5SOV`E!R&UPP=kgCApH!vAu#aRxvr~ z^x>hMvLuEr+&Hwjk+EwKd%;3`mV`F&{AK%5lanx~3@zT>G_>VGXeo!~vTEgkLViMM zWhUTcKR89yQbwN|&;s1vJMNBwM_~z80M0R7Envtmcp}eT3Ch;XW`27%^VvjAi$D$y zO_XfTiLku^3;X1y(L>B*^_V>OlK!qznOaN*kF==^MTo2cJ4ek9u(mx*_^uaA{0tMV z=3pK#Ycso7DQt8`nI@tF1l+CzVuu1LxOJSlRSQKXtsq45WC{mCtMe9+Dz=N5Zi#1S zCpu%!DQ<2UtVPodCeB1{)uq5FGhWG7AX}qq2NeK?)DUxBasu%2J|8cEH@TD1y8Dcw zUCxi`PD9a#A+&ts7Bmh(XeXLYNNj8f?GzK`%me`~w8!^st;B0ea7gZ08Cti9BCXv+ zJE6(wu@eGDp`{7vJ%)B>p`B{X!vPc!VHqQ>7TGk3Wyv+2&0NA!*=-|gG0GRUQwfMC z4C*PMX7EHlXOA9CDlsLs=s~Af2i2m9&6k69EAQ%q_$vV!xUXxvZs9YgE^7#9q+{uT z0(5(xiRL=fS?YXhJ^{y^ot&M$T-H(q&-^^bk32{oYIVztP-{!-cKY>o0#0RF26r1= zRrlthSVbeV1QKH5ia?dHTIfNR3~lYoa$KG&wAEyx`eGbf+hdWk!s)U?Taga`#L#9Q z+LCH`PYf+F{UNla-(qQKvxCr9umXYtd#$U`1tfeuB+g_U-tw}F2>x2VOmwdmd?czZ z20UFg3Dcj_^`xfiUud{JnMO8NJ&g$cDE|{=`NAupYEdbjq^5E--b6pHGmA?N*=maQ zQ|-16+k2>cm392d8lmpIR}4rX=}x-?udnIoSe*@s042vX%1?$bsQu4b8QgUBj{DMR z04FlG9$M-ahtM|T(1zF^gf_b#TDKu_nknRdOP38uL+e_O0ucCvPzT6DB~d4Zb{ee^ zy#lPY=ABG}W-f~|t9nl;3RK=f3qO<098%w;QJM)2zM7~mT5}_JKJ{J+uXd6J!NRhU z9RUFcQ$gis;YQ135t2DkFG@Jn?*4)6x$K6D3V0b#Tmksd8((AG=(Z24lo7q?v>Qn<}bPDBxNA z%zL$V@yIH3+zFP#I8bp9H`0zom2ba80~o9O3wpexyT8EwXkco)8J1HmxidFP#$Mls zPZtCbfghoW>+*J(;fwiH*2}Pg1dV$N0B67wVI~Crh2+I+g%Pmp}OmiuL`X=vS*S>ABPrWL9T|W6{^h>6sG1ew0wr~UFI{ViP-x9 zDrzG+Opt;~cP)cePz>$F8_x-yy((RObHB0{t|pVwPpFwm+YZ{RjVSe)IdLGKsqY8N z0?uPFx>T7P#X~|S!!S%GI4&6sDU4skx4SOGf|~vk{;mn4-vlcg$8Jn! zbW@qemdwe^Gwmkoh0j%{!m|q`Zr@3O5JG@Rvt>bwhx?e$co}*4;iBZ!WZ}D?td3n^ zLw?yzHp&gvsCc$JDm6IjWwkusLa$RTg3gT!ni=M0nrKk}JPobTGbD#|5*?>s%K^O>dUQ$Qv14C<;D=p?0ZwSD8d!0u44<#s87)JaqmAY`BRvNcQ6@D|zS3Y(b=cmQJhI3W$0hE->CJnslCdX0-w zXtUB)@f8#C>Ds0U&CxDXj_NHkk2v{vNc=uv2=(*L0Z zb{PjTGdW*Po)B6t05UiuSl^8qk3%WYgmEA2GBg_CRPY2~4WknJ_FUT^A*4zi&T~q& z2Q|hCfEqlT)mKlY6J6hPZ!%$>Sb5I4Gqs*tmW{YlkxCHnJ>jsE(;zS)Y7$dy27}0e zzbE)LC>T%z0Pcx!1Y2F39VAoS5MAsvLi;EclPRYvdfJG?6A>I-L)SC4UV#o1c+!_k zR&*z%RSRoOPiM-?%}bd^kj{)?*&OFY;$LBCZg_pv9T};WtY$^`PeaQg8n+m?=PZmC z)5b$vjzc?{{e7Wr+=;U(UAtYOZM4Ea;R+I=J!fbuOu#L)^Aj5nAvupJcTG^gLOaRM z-RsdUc^TS96xvcKdKtPx%z~aAf|apX;3v$NzCdgOI8Miuy#ktkY2?TSlD+g}jJfqP zpd&bE?E}p?ZBJNYWx<^tOOtbQSXnZ-VG6x@C(<}((dgP2?%-%$Rpz`6s0&bI-kU}j z5T>jy_eOK7w=U(dq8QrsQmeu*y?vSv(EqS}S?DCknB#;7jnFpMu-IjR&UJ~*oyFr_ z^+ZQ3EXx_%mjyqt6&k_w%o!8Nmk(4J@#P%Gnk^Dwki0WB=F7vo1h&}A+RJ3nN!0|>=-lb z(vyRNX#kwf;&{b9dG!kLAVDV-L!PO$07|!?noOszujBUGWwc}V8dAwYHKb8;NSs;8 z!F6VxO{IT}Vcr}9?~Z_wQ+++lqWciVr3wF+H7Svt22{3pZsw)LI5`9<2}2gg@99ZG zXitXF&Kq96sEou)5J20*CxQ&VAvv%lqh@VkN5|)gA-8~;vNh59v`x zbfLiIFlaot=n#25`pQwNc5HKxnBy%+m;Hc99K;gAoLw zI^)%h&{}V93x_+*u6hV9iJV^>+AzX}z*R}tnHX9qPt1nUYKIpPPAAe^sGJ!_FpbN6 zoTx4**x91CbQ?8SSebDygx=K>%E~KKt+ARCR!n$FSv7OdP`Wm;5w!o^nW>Q_rP}Zf zfJIVK5Kes@!5ToUx;tZc#unk&$33N!{wb50g+Z9Jsq2f1DTEik^lszqLY7RG?u|wk zohMT$yF*bBKuW6ba_Gf3dR9*<m;=0eO8LKhn7{+auixnMb8;p^al*Be7G#%Mxm8qed#_j=k{=6 z@ZyVpg|=ZSJ%skcU1J3_4x#nLu{Dk^FS(yOd97l#$B_+g-V>d$(l#`g(Ng`#R3(2c z)NeIAKc_)aJmOg-J0qqRff57)nDubA=m>o7L?)6yp|d@TI^37)IJ3c3Pm++zi76eN zEhW9p1=)xyoSNX)kq1Yj9=@3WXzo)8lsVq?iuj0ZLTl(55ty=1cKo4xI!$FMhsm_C zwR2&5M7k8*uFiyZ4&9-LHVgMg3@wIg3au*uRZgZyXbCQ!C7}hB0?>30C8Lu5w36jU z2rV6mWCv8%nPYtvT1n?%U|GqNJcRb5OeljGAj*|zT03}F0$8<+ww9t-DLG`rmC05$ z=&$M(NH)o;=3~IE?hw&Za&6$RfRpWo&-GL}vP7f!kiIV7RO(v^#=yQ9!H9@ zv;vyY4?s(UacFCWmSa`H7rX$(k37j@a@^$u>Y=4#g4d*i7hwU((AwwBrGA_V+B_3- z8dGH(b6*H|N3B#kVn9Qt3~CcN)~Y)fkO>3U8sI!v)Xk_<4$c6_XEu=scMtk~m9#G> zw=;I=R&v6_ucmr9Hmnb`K{dguu;H_!nAa7ql;bE-9{siYYK zrq~U&{djH|Zve7HOPpgvXzBWJJ+u{+`PmI-SrS?v730u)iy-+tg?6UU!bAw6g;scW zY-1Pjw(&$SYwGPy+>TD6tv$373u&CYESh=-O6EfNI-$|HZkqVj7b++xdUNyAs1&{j z@JmJDDEEbypLcE2B)y&n?=uM6$U=xK`$)5v`XXC!Bi?BVS0CHBYL>+Zjx%YT=rh&6 z1k(HVuyOBerTL8ec@N+M;EeFV%xv}IMQ@c%Hqh)^?Tt9<3x=R14yY%v{WSv_P%QfS(o>4b2 zqk5{`2?Z{2$iZw9ofY*j-Yr4DM#Lg@1`ABWrb6iZsGL7=sfEQFpA_4p(VvGhE~bJqPaN?ZG9M8mp+&tgtqk1W{>JC-xP3e_p95gwbdw*HWU#$szYXPC}H%{09W4sbJs1B-xtWa=p-k+$r$iz$lIHx43>M)u)j@7c7`TlG|;PT|c?Ye?* zGLBVOXD5{&p{-(QJvoxl1_>hkFq8XA-yyVgAPj!DRI*9@Vp zlh986xf?=DI}FZCXbnVeIGJijT)P9|5&Ox{;3Pmh7sJWfVB2aVAX8^EA@oY$A>PMT zi1)w;h(_apS35>C_OC#HFZj2|-FpG7*$BVL??70(*%I(G7i0}La@1@fzh*c+`#Af$=jZk_9M{L^ zb8)X0+6!V^wUCMdKHoHz^vkrO@t+$17WjbqiT%WL|8Zwji761RekIC|HpsoU%&g`+aTY5 zyI`#C9|M*}3y~~{QB!}z4ggQ zAAR`Yhd;DmAAb1JN1wd)*6XkT;Dh(S{4f95ulL9Q%Qx>JJ^qK^|0j>iAOGuLKPy!# zbFV?&!K(7)Q02qEpPn`J?z|r{PER z;ivL1iht&Lj(>Ud;K7S8J$~=)&%gTg!|%TG@ao3tL;SjNb>rcUho`4E>|bAd>x1{- ze($B1UVQNAXw%uJ?~2a9NKxFFrncm71l@mv4m_rB2=t6hiyU*ry- z(sl7O5f1ymep3`r+noH(xi{3)3m(I{`J+ys`zvzk;LyP~EuZnH| z?f>c5&onqBZF@F#ji^kbCeZ^^9^=X#DFbCek(*}3H8drcHK6MxeKpI4%daC}j*oqL z1YkB$c~h$js9Oexuabi=cV(}^-eA4=_9NqE4v}D3if*sJw1C*l#jCQ6$n^nzQ4GPf zk9oRfmfX@;#v8N7TkmhQy;FV1FM#B*egVnx4g2;*cUg4p9-kGz7QSq^QjV-vj~+dG z@$uX5|KP0;Km6XSuRQzHFWyuejm;Q`*%AWdQX+E2w#~QlyBmn?d{fQDmj3g;K{)U&d&;a+z_ce z*SomVcec!U?~5OQ`pG+Qy!OiT&p*%e!hgko;U6A8|NLujyz|!UU%mSt&yV%fPd{xx z>3*x1u=XEt+w)c66(~6-*%?lbr}VSt@!ebb8;cXL55d3>XRpCy#y{e7cvRs3yBIb* zHvAa0R9h#ZP0k`5BnoXfIoOhcBh8VAhF~)%eNViXzwbgG6Cce}kxeRxqO!Z8bk&69 zV7(GC`0TPLVPrrSQxlV;AKtRAPaao2WPYZv!r8zRM6Up^zSrrGkMXCGAD}pFhOZT_ zn63R2q1lELme&eOrI;MWkQ^NY&Nn~@nO!HJfAQ5PAN};Zc4S-~Cd3V#8NBsu)Y4JSuTj;>1|?LH)j{brw(4?pR?+r}R{{=W8a(T9UK zhPL|$gq9}<-7&~x&~jxa3p#ZsQTZ5jKneg(67jXUx@Goamafk_*RRZEWF?8Ae!k578f>vgR-c3ZuIUT=M8AG+HVJV4j>kClf5 zH|*t*3A~=R{!}RcF8xo)nSSMW5R(J^g-~bT-&?AmZEL?(cc6U^c|$7%rpsl7T$xTAjoe#77U_{_&?eG(!D(#p5A8 zKu%Bnw^L<@{dRTr+B>g*fb`h#j8k2@(lx-!r!Sti-&l}Zay-X^l&`mEcEl1LKTN(K z9(Gimw|Ma6>%G0^qa%LJ^>7a4D)*lp+CFD!3lFX8Fot$-*UGbVfc{>{NOPUvZCFSy zMCe&Kvu>fu#r%$(FV9Q~B+I)4Ml`CES-|09V#;2Mao_KB3_Anu3-LfEkMsimK3bVw#D?(%zl0#zA6DRCeU^C1GhMopC$&_bDMg4bBvt~5l zq0X3Auv3@R$Bz8m1PtKLL8^_-JD42oOzj=*^g`K~O=5zc;l0eD+B8}=UhhmzyjGU2Rpu>Lt{$*zGimmy3gS78?}AVwYO1;K%eOirRo zUJy0zeD3r`D|6J!w#9I(hBu^*)urC{UI!*>Q&rl#UFh&R9Am@DB_3PQ|(w^bd zpK|;SKJe)_Z&CB1=6K=W`Mr9mIZ$DAPvf{nMToES)R#a0(NA$|T!m_a8Q|x`m8XCg zrB^rNAu`Gz)*e52&$8pzCAxMb@n+p=Xot6+$#HvmteRuTvrQAdz0bdVn6pKDvSZTo z{8(+6VLN-<^-+Erb@7HtLfel*TjU3!MP}^^7NinipHA;PQv?0Rg|steAu1XAGocKC zx|wlJSHpx0X3G_{Gbz(u&4~PI%791~h+*o8KyAV&?0SR)GXzT=lY?)p-yfqvM;FIM zU2Jf57Vct8+qNvVlHM<=GrBnQ2q$@3n-;%`GO|&WGzZ8J4fZk zsEs}RyR^eSRd(?3Shx17dmA&LK~VeTHOFm3Wotq@bf!H2H$%h0S94VKaooZ4uIti% z#Am7f6GNN-iqLXyi)-asM?p|mX6Afy91nL$K?3HaoF@K?uE)vBXGS@?8} zJ2e~}-un2Zb0o*JSORfE+7I7Rtx>VX(CgEWGz!I=e-$s3CniUFvs{hFAo$#e58qJb zv1yeY#roDdj4?uTsOIRBJ zk^@aA_y%C3Wu6@1`11fj4!a)0HK%)7955fhpz@xvZmA%H?pMaxP-5L z#`$zshJvPXrzA^`Z=iwlpKaT%Zy~X7-qb>*PY2kjBW%97-utl<&H`2wH`hBGdUq&6 zth)8#_zHJOtA69=C1(KrFktJfzTd5$(wyVoJ&n)3c(>-sKL6$pdzAOS`qB5S+PE4j z2{a(52hA&PnK^TGj76fKIbFx4)s@j4L zFH>Z?myp)AXuv_i8)~=C84_bIM-d3np&dCPCTU7VJgYPtS$Ne0gB{8x^v9dh!nERr zgCW?yKfDS$-l&{UgkQG`jhTDB?c6%;!uVXvw+;T*a-{Dsdtc94kXk=byh{%Iyv}QU zjn9|&JURNfn9#Aju`Y#Eud5s0c$}UdoDoUAapnI@np+hpDpgdXUcL6lTfACSHTA>% z(`%09bAGLaer1*OSX^nOnft-ng&`fw>h5MZ3EIND6a2UKiJ`T$*KfHpsb6)ShZf^8 z`)jnaXPK+5odfKDY(BWAiDgH~aV^?AV3okm)}ZT5BMqYxlOiLjgY(qJ)j%VBGf3_Y zZZ}cGPmpcsp7C0Fa&nCBhWN*Lau(Yz{n+r2WE`5z;Qemy;=gp>(slM!YVlSpIWF@s zw%3=seDwIUPe0PJ5tCzRQxAHTFf2VCjl*sXU2Ql=UVHsr+sBP2-hJp+UN9Jul4G|k zk{7JHye*Qs`RG@hj?Z;dKj9{vaM^A6~rQ1-5c0nFq+ z$XkX0LTv50i4nk<5D-biT?FS}^2CuG7w!)qoNsNsUa98Li?f5URU5YMMlnhEBYe$B z?QP#BRme8fZAnq?4?ouzeO!z0IQc2sn<1o6NDhylZHqh04PGgurO9bBBTxRxqv7i6 zaO80~`at@;@zw{{wZwNxLs(A^YZ;Xss5tk1?8a4G`Sde1ztL#`JYUP-%- zh1%a6+FqfJ-AbJuFJuma8evL6YNZ1J$#F58&D=NLBS}_c z4T!Q?J6;nz7K$TQWU^Ohrem{&5P*-*t*5)pS4ok$;yj`Y%i2vJw%mQ3WBCQK$y*(q zX!P4wx2Z;Dw%k{#Wgp1#h2@6b++kzOnQf8~
TV{barxR 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 R6DI%w002ovPDHLkV1gh0hcy5I literal 0 HcmV?d00001 diff --git a/Media/tic-tac-toe.png.meta b/Media/tic-tac-toe.png.meta new file mode 100644 index 0000000..0dab28e --- /dev/null +++ b/Media/tic-tac-toe.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: a76f3d6023e554561b6c086620fe3d81 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md new file mode 100644 index 0000000..9c2e4b6 --- /dev/null +++ b/README.md @@ -0,0 +1,209 @@ +![Static Badge](https://img.shields.io/badge/english-118027) +![Static Badge](https://img.shields.io/badge/russian-0390fc) +

+ + + + Unity client Shardy + +

+

Unity client for Shardy

+

Framework for games and apps

+

+ Quick start · Docs · Shardy · Service template · Report Bug +

+ +# 💬 Overview + +This package is a Unity client for Shardy. It provides RPC framework with simple user-friendly API: requests, commands and subscribe for communication with Shardy microservices. + +Shardy is a framework for online games and applications for Node.js. It provides the basic functionality for building microservices solutions: mobile, social, web, multiplayer games, realtime applications, chats, middleware services, etc. + +[Read about Shardy](https://github.com/mopsicus/shardy) 💪 + +# ✨ Features + +- Simple API: request, response, subscribe, etc +- Socket and Websocket communication +- iOS, Android and WebGL support +- Lightweight and fast +- Support custom serialization +- Support custom handshake validation +- Connection heartbeat support +- Good reference materials: docs, snippets, samples +- No 3rd party libs + +# 🚀 Usage + +### Installation + +Get it from [releases page](https://github.com/mopsicus/shardy-unity/releases) or add the line to `Packages/manifest.json` and module will be installed directly from Git url: + +``` +"com.mopsicus.shardy": "https://github.com/mopsicus/shardy-unity.git", +``` + +### Environment setup + +For a better experience, you can set up an environment for local development. Since Shardy is developed with VS Code, all settings are provided for it. + +1. Use `Monokai Pro` or `eppz!` themes +2. Use `FiraCode` font +3. Install extensions: + - C# + - C# Dev Kit + - Unity +4. Enable `Inlay Hints` in C# extension +5. Install `Visual Studio Editor` package in Unity +6. Put `.editorconfig` in root project directory +7. Be cool + +### Quick start + +See the sample section to get a [demo app](./Samples~/Demo). This demo shows you how to use client's methods and options. If you want to test your own demo backend, see how to install and launch [service template](https://github.com/mopsicus/shardy-template). + +_Tested in Unity 2022.3.x, Android, iOS and WebGL._ + +

+ + Demo on Shardy + +

+ +### Tic-Tac-Toe + +Also, in sample section you can get [Tic-Tac-Toe](./Samples~/TicTacToe) multiplayer online game example. Explore the example to get in mind how you can organize your client-server communation and how to start developing your new multiplayer game or add a multiplayer feature to an existing game. + +

+ + Tic-Tac-Toe on Shardy + +

+ +See the [game server](https://github.com/mopsicus/shardy-tictactoe) for Tic-Tac-Toe. Get a simplest server example made on Shardy for testing and development. + +### Requests and commands + +The general difference between requests and commands that is other side must respond to requests and doesn't respond to commands. So this means that when you make a request, you have a callback with response data. And when you send a command, you are simply notifying the other side about something. + +Request: + +```csharp +_client.Request("test", (data) => { + Console.WriteLine($"received test data: ${data.ToString()}"); +}); +``` + +Command: + +```csharp +_client.Command("start"); +``` + +Subscribe: + +```csharp +_client.On("lookup", (data) => { + Console.WriteLine($"received lookup data: ${data.ToString()}"); +}); +``` + +Subscribe on request: + +```csharp +_client.OnRequest(request, (payload) => { + Console.WriteLine($"received request data: ${payload.ToString()}"); + // if comment line below, you will give timeout on your backend + _client.Response(payload, Encoding.UTF8.GetBytes("some_data_from_client")); +}); +``` + +### Validation + +When a client connects to the server, it must successfully complete the handshake before it can begin. Shardy uses a two-step handshake for connections. + +Stages of handshake: + +1. The client sends a handshake to the server +2. Server receives and verifies it: + - Sends an acknowledgement to the client + - Disconnects the client, if the verification fails +3. The client receives the acknowledgement and verifies it: + - Sends a reply acknowledgement to the server + - Disconnects, if the verification fails +4. After verifying the handshake and acknowledgement, the client and server can communicate with each other + +If your implementation doesn't need to do a two-step handshake, you can set "stubs" on these methods. + +Shardy provides an interface for handshake validation. You can implement your own handshake data structure and validation for all these stages. Create your validator class, implement `IValidator` interface methods and pass it to your service and client. + +```csharp +using Shardy; + +class MyHandshake : IValidator { + + public ValidatorState VerifyAcknowledgement(byte[] body) { + // vefify acknowledgement data + } + + public byte[] Handshake(byte[] body = null) { + // data for initial handshake + } + + public byte[] Acknowledgement(byte[] body) { + // data for acknowledgement after handshake validation passed + } +} +``` + +### Serialization + +Shardy supports custom serialization of transmitted data. You can use JSON, MessagePack, Protobuf, FlatBuffers, etc. or your own serializer. + +Create your serializer class, implement `ISerializer` methods and pass it to your service and client. + +```csharp +using Shardy; + +class MyJsonSerializer : ISerializer { + + public byte[] Encode(PayloadData body) { + // encode PayloadData to byte array for transporting + } + + public PayloadData Decode(byte[] body) { + // decode recevied data and serialize to PayloadData + } +} +``` + +See [documentation](./Documentation~/index.md) for information on all classes and methods. + +# 🏗️ Contributing + +We invite you to contribute and help improve Unity client for Shardy. Please see [contributing document](./CONTRIBUTING.md). 🤗 + +You also can contribute to the Shardy project by: + +- Helping other users +- Monitoring the issue queue +- Sharing it to your socials +- Referring it in your projects + +# 🤝 Support + +You can support Shardy by using any of the ways below: + +* Bitcoin (BTC): 1VccPXdHeiUofzEj4hPfvVbdnzoKkX8TJ +* USDT (TRC20): TMHacMp461jHH2SHJQn8VkzCPNEMrFno7m +* TON: UQDVp346KxR6XxFeYc3ksZ_jOuYjztg7b4lEs6ulEWYmJb0f +* Visa, Mastercard via [Boosty](https://boosty.to/mopsicus/donate) +* MIR via [CloudTips](https://pay.cloudtips.ru/p/9f507669) + +# ✉️ Contact + +Before you ask a question, it is best to search for existing [issues](https://github.com/mopsicus/shardy-unity/issues) that might help you. Anyway, you can ask any questions and send suggestions by [email](mailto:mail@mopsicus.ru) or [Telegram](https://t.me/mopsicus). + +# 🔑 License + +Unity client for Shardy is licensed under the [MIT License](./LICENSE.md). Use it for free and be happy. 🎉 \ No newline at end of file diff --git a/README.md.meta b/README.md.meta new file mode 100644 index 0000000..2a6d9da --- /dev/null +++ b/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7a3a2e11d4d2e4995929fcf1bce9a6b3 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000..add2887 --- /dev/null +++ b/README.ru.md @@ -0,0 +1,209 @@ +![Static Badge](https://img.shields.io/badge/english-118027) +![Static Badge](https://img.shields.io/badge/russian-0390fc) +

+ + + + Unity клиент Shardy + +

+

Unity клиент для Shardy

+

Фреймворк для игр и приложений

+

+ Быстрый старт · Документация · Shardy · Пример сервиса · Отчёт об ошибке +

+ +# 💬 Описание + +Это Unity клиент для Shardy. Он предоставляет RPC-фреймворк с простым и удобным API: запросы, команды и подписки для взаимодействия с Shardy-сервисами. + +Shardy – это фреймворк для онлайн игр и приложений на Node.js. Он предоставляет базовую функциональность для построения микросервисных решений: мобильных, социальных, веб, многопользовательских игр, приложений реального времени, чатов, middleware сервисов и т.п. + +[Узнать про Shardy](https://github.com/mopsicus/shardy) 💪 + +# ✨ Возможности + +- Простой API: запросы, команды, подписки и т.п. +- Транспорт данных через сокеты и вебсокеты +- iOS, Android и WebGL поддержка +- Легкий и быстрый +- Поддержка пользовательской сериализации +- Поддержка пользовательской валидации рукопожатий (handshake) +- Настраиваемый heartbeat для соединения +- Справочные материалы: документация, сниппеты, примеры +- Не используются сторонние библиотеки + +# 🚀 Использование + +### Установка + +Скачайте пакет со страницы [релизов](https://github.com/mopsicus/shardy-unity/releases) или добавьте строчку ниже в ваш файл `Packages/manifest.json` и пакет будет установлен по адресу Git репозитория: + +``` +"com.mopsicus.shardy": "https://github.com/mopsicus/shardy-unity.git", +``` + +### Настройка окружения + +Настройте своё окружение для локальной разработки для удобства и "синхронизации" с текущим проектом. Так как Unity клиент для Shardy разрабатывается с использованием редактора VS Code, то все настройки и рекомендации предложены для него. + +1. Используйте `Monokai Pro` или `eppz!` тему +2. Используйте `FiraCode` шрифт +3. Установите расширения: + - C# + - C# Dev Kit + - Unity +4. Включите `Inlay Hints` в настройках C# расширения +5. Установить пакет `Visual Studio Editor` в редакторе Unity +6. Поместите файл `.editorconfig` в корневую папку проекта +7. Ура! + +### Быстрый старт + +Посмотрите раздел с примерами и скачайте [демо приложение](./Samples~/Demo). Это демо покажет вам как использовать методы клиента и какие есть опции. Если вы хотите использовать для тестов собственный backend, посмотрите как установить и запустить [пример сервиса](https://github.com/mopsicus/shardy-template). + +_Протестировано в Unity 2022.3.x, Android, iOS и WebGL._ + +

+ + Demo on Shardy + +

+ +### Крестики-Нолики + +Также, из раздела с примерами вы можете взять демо клиента для многопользовательской онлайн игры [Крестики-Нолики](./Samples~/TicTacToe). Изучите пример чтобы понять, как работает клиент-серверное взаимодействие и как начать разрабатывать свою собственную онлайн игру, или как добавить мультиплеер в уже существующую. + +

+ + Tic-Tac-Toe on Shardy + +

+ +Посмотрите [пример сервера](https://github.com/mopsicus/shardy-tictactoe) для игры Крестики-Нолики. Скачайте, изучите и протестируйте простой игровой сервер сделанный на Shardy. + +### Запросы и команды + +Главное отличие между запросами и командами – серверная сторона должна ответить на запрос и не должна на команду. Это означает, что когда вы делаете запрос, у вас есть функция обратного вызова (callback) и когда сервер ответит, в неё придёт результат. Когда вы отправляете команду, то вы просто "информируете" сервер о чём-то. + +Запрос: + +```csharp +_client.Request("test", (data) => { + Console.WriteLine($"received test data: ${data.ToString()}"); +}); +``` + +Команда: + +```csharp +_client.Command("start"); +``` + +Подписка: + +```csharp +_client.On("lookup", (data) => { + Console.WriteLine($"received lookup data: ${data.ToString()}"); +}); +``` + +Подписка на запрос с сервера: + +```csharp +_client.OnRequest(request, (payload) => { + Console.WriteLine($"received request data: ${payload.ToString()}"); + // если закомментировать строку ниже, вы получите таймаут на сервере + _client.Response(payload, Encoding.UTF8.GetBytes("some_data_from_client")); +}); +``` + +### Валидация + +Когда клиент подключается к серверу, он должен успешно завершить рукопожатие (handshake) перед началом работы. В Shardy используется двухэтапное рукопожатие для соединений. + +Этапы рукопожатия: + +1. Клиент отправляет данные рукопожатия на сервер +2. Сервер получает и проверяет их: + - Отравляет подтверждение клиенту + - Отключает клиента, если проверка не прошла +3. Клиент получает данные подтверждения и тоже проверяет их: + - Отправляет ответ на подтверждение серверу + - Отключается, если проверка не прошла +4. После успешного рукопожатия и подтверждения, клиент и сервер могут отправлять друг другу запросы и команды. + +Если в вашей реализации нет необходимости делать двухэтапное рукопожатие, вы можете установить "заглушки" на этих методах. + +Shardy предоставляет интерфейс для валидации рукопожатия. Вы можете реализовать собственную структуру данных рукопожатия и валидацию для всех этих этапов. Создайте свой класс с валидатором, релизуйте интерфейс `IValidator` и передайте его в конструктор клиента. + +```csharp +using Shardy; + +class MyHandshake : IValidator { + + public ValidatorState VerifyAcknowledgement(byte[] body) { + // vefify acknowledgement data + } + + public byte[] Handshake(byte[] body = null) { + // data for initial handshake + } + + public byte[] Acknowledgement(byte[] body) { + // data for acknowledgement after handshake validation passed + } +} +``` + +### Сериализация + +Shardy поддерживает пользовательскую сериализацию передаваемых данных. Вы можете использовать JSON, MessagePack, Protobuf, FlatBuffers и т.д. или свой собственный сериализатор. + +Создайте свой класс с сериализатором, релизуйте интерфейс `ISerializer` и передайте его в конструктор клиента. + +```csharp +using Shardy; + +class MyJsonSerializer : ISerializer { + + public byte[] Encode(PayloadData body) { + // encode PayloadData to byte array for transporting + } + + public PayloadData Decode(byte[] body) { + // decode recevied data and serialize to PayloadData + } +} +``` + +Смотрите [документацию](./Documentation~/index.md) с информацией о всех классах и методах. + +# 🏗️ Развитие + +Мы приглашаем вас внести свой вклад и помочь улучшить Unity клиент для Shardy. Пожалуйста, ознакомьтесь с [документом](./CONTRIBUTING.md). 🤗 + +Вы также можете внести свой вклад в проект Shardy: + +- Помогая другим пользователям +- Мониторя список существующих проблем +- Рассказав о проекте в своих соцсетях +- Используя его в своих проектах + +# 🤝 Поддержка + +Вы можете поддержать проект любым из способов ниже: + +* Bitcoin (BTC): 1VccPXdHeiUofzEj4hPfvVbdnzoKkX8TJ +* USDT (TRC20): TMHacMp461jHH2SHJQn8VkzCPNEMrFno7m +* TON: UQDVp346KxR6XxFeYc3ksZ_jOuYjztg7b4lEs6ulEWYmJb0f +* Карты Visa, Mastercard через [Boosty](https://boosty.to/mopsicus/donate) +* Карты МИР через [CloudTips](https://pay.cloudtips.ru/p/9f507669) + +# ✉️ Контактная информация + +Перед тем как задать вопрос, лучшим решением будет посмотреть уже существующие [проблемы](https://github.com/mopsicus/shardy-unity/issues), это может помочь. В любом случае, вы можете задать любой вопрос или отправить предложение по [email](mailto:mail@mopsicus.ru) или [Telegram](https://t.me/mopsicus). + +# 🔑 Лицензия + +Unity клиент для Shardy выпущен под лицензией [MIT](./LICENSE.md). Используйте бесплатно и радуйтесь. 🎉 \ No newline at end of file diff --git a/README.ru.md.meta b/README.ru.md.meta new file mode 100644 index 0000000..cfb0ed6 --- /dev/null +++ b/README.ru.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5d60f773fe8d7412884aabc0cd6e0219 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime.meta b/Runtime.meta new file mode 100644 index 0000000..90980d9 --- /dev/null +++ b/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d0d3c0715350147c2855eebe99a5e6a5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Block.cs b/Runtime/Block.cs new file mode 100644 index 0000000..238cd02 --- /dev/null +++ b/Runtime/Block.cs @@ -0,0 +1,62 @@ +using System; + +namespace Shardy { + + /// + /// Block data for transport + /// + class Block { + + /// + /// Length of block head + /// + public const int HEAD_SIZE = 4; + + /// + /// Encode block for transporting + /// + /// First byte is type + /// Next - length, and data + /// + /// Block type: data, kick or heartbeat + /// Body to send + /// Encoded type + body + public static byte[] Encode(BlockType type, byte[] body) { + var length = (body != null) ? HEAD_SIZE + body.Length : HEAD_SIZE; + var buffer = new byte[length]; + var index = 0; + buffer[index++] = Convert.ToByte(type); + buffer[index++] = Convert.ToByte(body.Length >> 16 & 0xFF); + buffer[index++] = Convert.ToByte(body.Length >> 8 & 0xFF); + buffer[index++] = Convert.ToByte(body.Length & 0xFF); + while (index < length) { + buffer[index] = body[index - HEAD_SIZE]; + index++; + } + return buffer; + } + + /// + /// Decode block data + /// + /// Buffer with data to decode + /// Result with type as BlockType and body as byte array + public static BlockData Decode(byte[] data) { + var type = (BlockType)data[0]; + var body = new byte[data.Length - HEAD_SIZE]; + for (var i = 0; i < body.Length; i++) { + body[i] = data[i + HEAD_SIZE]; + } + return new BlockData(type, body); + } + + /// + /// Check received block + /// + /// Byte index for BlockType + /// Is correct block or not + public static bool Check(BlockType type) { + return Enum.IsDefined(typeof(BlockType), type); + } + } +} \ No newline at end of file diff --git a/Runtime/Block.cs.meta b/Runtime/Block.cs.meta new file mode 100644 index 0000000..1eaf5ac --- /dev/null +++ b/Runtime/Block.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 318053597490d475381fdb076c14f474 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/BlockData.cs b/Runtime/BlockData.cs new file mode 100644 index 0000000..f4e05a1 --- /dev/null +++ b/Runtime/BlockData.cs @@ -0,0 +1,34 @@ +namespace Shardy { + + /// + /// Block result after decode + /// + public struct BlockData { + + /// + /// Type of block + /// + public BlockType Type; + + /// + /// Data length + /// + public int Length; + + /// + /// Data bytes array + /// + public byte[] Body; + + /// + /// Constructor + /// + /// Block type + /// Data for block + public BlockData(BlockType type, byte[] body) { + Type = type; + Length = body.Length; + Body = body; + } + } +} \ No newline at end of file diff --git a/Runtime/BlockData.cs.meta b/Runtime/BlockData.cs.meta new file mode 100644 index 0000000..764e380 --- /dev/null +++ b/Runtime/BlockData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30ba0b5dd62634b909a632b6b71f065d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/BlockType.cs b/Runtime/BlockType.cs new file mode 100644 index 0000000..3bf1767 --- /dev/null +++ b/Runtime/BlockType.cs @@ -0,0 +1,33 @@ +namespace Shardy { + + /// + /// Block type to encode + /// + public enum BlockType { + + /// + /// Handshake process + /// + Handshake, + + /// + /// Acknowledgement for success verify + /// + HandshakeAcknowledgement, + + /// + /// Ping + /// + Heartbeat, + + /// + /// Data for command, request, response + /// + Data, + + /// + /// Kick from server, disconnect + /// + Kick + } +} \ No newline at end of file diff --git a/Runtime/BlockType.cs.meta b/Runtime/BlockType.cs.meta new file mode 100644 index 0000000..d5a8866 --- /dev/null +++ b/Runtime/BlockType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff6e9e4777f9144a7b799717a87fb41b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Client.cs b/Runtime/Client.cs new file mode 100644 index 0000000..3c2945b --- /dev/null +++ b/Runtime/Client.cs @@ -0,0 +1,234 @@ +using System; + +namespace Shardy { + + /// + /// Client class connected to server + /// + public class Client { + + /// + /// Log tag + /// + const string TAG = "CLIENT"; + + /// + /// Event on connected + /// + public Action OnConnect = delegate { }; + + /// + /// Event on disconnected + /// + public Action OnDisconnect = delegate { }; + + /// + /// Event when ready to work + /// + public Action OnReady = delegate { }; + + /// + /// Commander instance + /// + readonly Commander _commander = null; + + /// + /// Client validator + /// + readonly IValidator _validator = null; + + /// + /// Client serializer + /// + readonly ISerializer _serializer = null; + + /// + /// Current connection + /// + readonly Connection _connection = null; + + /// + /// Current options + /// + readonly ClientOptions _options = null; + + /// + /// Snd handshake after connect + /// + readonly byte[] _handshake = null; + + /// + /// Is client connected + /// + public bool IsConnected { + get { + return _connection.IsConnected; + } + } + + /// + /// Client constructor + /// + /// Validator + /// Serializer + /// Client options (optional) + /// Handshake after connect (optional) + public Client(IValidator validator, ISerializer serializer, ClientOptions options = null, byte[] handshake = null) { +#if UNITY_WEBGL && !UNITY_EDITOR + WebSocketManager.Init(); +#if SHARDY_DEBUG_RAW + WebSocketManager.SetDebug(true); +#endif +#endif + _validator = validator; + _serializer = serializer; + _options = options ?? new ClientOptions(); + _handshake = handshake; +#if UNITY_WEBGL && !UNITY_EDITOR + if (_options.Type == TransportType.Tcp) { + Logger.Error($"Unable to use TCP transport for WebGL", TAG); + return; + } +#endif + _connection = new Connection(_options.Type, _options.BufferSize); + _commander = new Commander(_connection, _validator, _serializer, _options); + _commander.OnDisconnect = (reason) => OnDisconnect(reason); + _commander.OnReady = () => OnReady(); + } + + /// + /// Connect to server + /// + /// Host to connect + /// Port to connect + public async void Connect(string host, int port) { + var status = await _connection.Open(host, port); + if (status) { + _commander.Start(); + } + OnConnect(status); + if (_handshake != null && status) { + Handshake(_handshake); + } + } + + /// + /// Disconnect from server + /// + public void Disconnect() { + _commander.Disconnect(); + } + + /// + /// Send command (event) to server + /// + /// Command name + /// Payload data + public void Command(string command, byte[] data = null) { + _commander.Command(command, data); + } + + /// + /// Send request to server and wait response + /// + /// Request name + /// Answer from server + /// Request id + public int Request(string request, Action callback) { + return Request(request, null, callback); + } + + /// + /// Send response on request from server + /// + /// Request data + /// Data + public void Response(PayloadData request, byte[] data = null) { + _commander.Response(request, data); + } + + /// + /// Send error on request from server + /// + /// Request data + /// Error message or code + /// Data + public void Error(PayloadData request, string error, byte[] data = null) { + _commander.Error(request, error, data); + } + + /// + /// Send request to server and wait response + /// + /// Request name + /// Payload data + /// Answer from server + /// Request id + public int Request(string request, byte[] data, Action callback) { + return _commander.Request(request, data, callback); + } + + /// + /// Cancel request manually + /// + /// Request id + public void CancelRequest(int id) { + _commander.CancelRequest(id); + } + + /// + /// Handshake to verify connection + /// + /// Data for handshake + public void Handshake(byte[] body = null) { + _commander.Handshake(_validator.Handshake(body)); + } + + /// + /// Subscribe on command from server + /// + /// Command name + /// Callback to action + public void On(string command, Action callback) { + _commander.AddCommand(command, callback); + } + + /// + /// Unsubscribe from command + /// If callback is null -> clear all of them + /// + /// Command name + /// Callback to unsubscribe + public void Off(string command, Action callback = null) { + _commander.CancelCommand(command, callback); + } + + /// + /// Subscribe on request from server that wait response + /// + /// Request name + /// Callback to action + public void OnRequest(string request, Action callback) { + _commander.AddOnRequest(request, callback); + } + + /// + /// Unsubscribe from request from server that wait response + /// + /// Request name + /// Callback to unsubscribe + public void OffRequest(string request) { + _commander.CancelOnRequest(request); + } + + /// + /// Destroy all + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + _commander.Destroy(); + } + } +} \ No newline at end of file diff --git a/Runtime/Client.cs.meta b/Runtime/Client.cs.meta new file mode 100644 index 0000000..f5dd719 --- /dev/null +++ b/Runtime/Client.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fafaccae986214a3798477d5bafdcb8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ClientOptions.cs b/Runtime/ClientOptions.cs new file mode 100644 index 0000000..32d6b46 --- /dev/null +++ b/Runtime/ClientOptions.cs @@ -0,0 +1,50 @@ +namespace Shardy { + + /// + /// Client and connection options + /// + public class ClientOptions { + + /// + /// Transport type: TCP or WebSocket + /// + public TransportType Type = TransportType.Tcp; + + /// + /// Transport buffer size + /// + public int BufferSize = 1024; + + /// + /// Timeout for RPC request (ms) + /// + public float RequestTimeout = 10000f; + + /// + /// Interval for checking server (ms) + /// + public float PulseInterval = 1000f; + + /// + /// Options constructor + /// + /// Transport type + public ClientOptions(TransportType type = TransportType.Tcp) { + Type = type; + } + + /// + /// Options constructor + /// + /// Transport type + /// Transport buffer size, Kb + /// Timeout for RPC request, ms + /// Interval for checking server, ms + public ClientOptions(TransportType type, int buffer, float timeout, float pulse) { + Type = type; + BufferSize = buffer; + RequestTimeout = timeout; + PulseInterval = pulse; + } + } +} \ No newline at end of file diff --git a/Runtime/ClientOptions.cs.meta b/Runtime/ClientOptions.cs.meta new file mode 100644 index 0000000..8595c14 --- /dev/null +++ b/Runtime/ClientOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32ef8554eb36544889f30ee0f64ab8d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Commander.cs b/Runtime/Commander.cs new file mode 100644 index 0000000..78a8e92 --- /dev/null +++ b/Runtime/Commander.cs @@ -0,0 +1,595 @@ +using System; +using System.Collections.Generic; +using System.Threading; + +#pragma warning disable 4014 + +namespace Shardy { + + /// + /// Client commander to send/receive commands and requests + /// + class Commander { + + /// + /// Log tag + /// + const string TAG = "COMMANDER"; + + /// + /// Timer timeout loop + /// + const float TIMEOUT_INTERVAL = 1000f; + + /// + /// Timeout error code + /// + const string TIMEOUT_ERROR = "timeout"; + + /// + /// Callback on disconnect + /// + public Action OnDisconnect = delegate { }; + + /// + /// Cached ready callback + /// + public Action OnReady = delegate { }; + + /// + /// Dictionary of request id and commands + /// + readonly Dictionary _names = null; + + /// + /// Dictionary of notify command and their callbacks + /// + readonly Dictionary>> _commands = null; + + /// + /// Dictionary of request id and callback + /// + readonly Dictionary> _callbacks = null; + + /// + /// Dictionary of request name and callback for requests from server + /// + readonly Dictionary> _requests = null; + + /// + /// Dictionary of request id and start using time + /// + readonly Dictionary _timeouts = null; + + /// + /// Protocol instance + /// + readonly Protocol _protocol = null; + + /// + /// Pulse instance + /// + Pulse _pulse = null; + + /// + /// Current request counter + /// + int _counter = 1; + + /// + /// Validator + /// + readonly IValidator _validator = null; + + /// + /// Serializer + /// + readonly ISerializer _serializer = null; + + /// + /// Current options + /// + readonly ClientOptions _options = null; + + /// + /// Cancellation token source + /// + readonly CancellationTokenSource _cancellation = new CancellationTokenSource(); + + /// + /// Cached disconnect reason + /// + DisconnectReason _disconnectReason = DisconnectReason.Normal; + + /// + /// Creates an instance of Commander + /// + /// Client connection + /// Current validator + /// Current serializer + /// Client options + public Commander(Connection connection, IValidator validator, ISerializer serializer, ClientOptions options) { + _validator = validator; + _serializer = serializer; + _options = options; + _names = new Dictionary(); + _commands = new Dictionary>>(); + _callbacks = new Dictionary>(); + _requests = new Dictionary>(); + _timeouts = new Dictionary(); + _protocol = new Protocol(connection); + _protocol.OnBlock = (block) => OnBlock(block); + _protocol.OnDisconnect = () => OnClose(); + } + + /// + /// Start use + /// + public void Start() { + Utils.SetTimer(TIMEOUT_INTERVAL, _cancellation, () => TimeoutCheck()); + _pulse = new Pulse(_options.PulseInterval); + _pulse.OnPulse = () => OnPulse(); + _protocol.Start(); + } + + /// + /// Timer check for timeout RPC call + /// + void TimeoutCheck() { + foreach (var id in _timeouts.Keys) { + var span = DateTime.Now - _timeouts[id]; + var timeout = (int)span.TotalMilliseconds; + if (timeout > _options.RequestTimeout) { + var payload = new PayloadData(); + payload.Type = PayloadType.Response; + payload.Id = id; + payload.Name = _names[id]; + payload.Error = TIMEOUT_ERROR; + OnPayload(payload); + } + } + } + + /// + /// Add callback for request + /// + /// Request id + /// Request command + /// Request's params + /// Callback for request + void AddRequest(int id, string command, byte[] param, Action callback) { + if (_callbacks.ContainsKey(id)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"callback already exists: {id}, method: {_callbacks[id].Method}", TAG); +#endif + } else { + if (id <= 0) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"callback id can't be less 1: {id}", TAG); +#endif + return; + } + _names.Add(id, command); + _callbacks.Add(id, callback); + _timeouts.Add(id, DateTime.Now); + } + } + + /// + /// Remove request from list + /// + /// Request id + public void CancelRequest(int id) { + if (!_callbacks.ContainsKey(id)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown callback to cancel: {id}", TAG); +#endif + return; + } + _names.Remove(id); + _callbacks.Remove(id); + _timeouts.Remove(id); + } + + /// + /// Exec callback + /// + /// Data for callback + void InvokeRequest(PayloadData payload) { + if (!_callbacks.ContainsKey(payload.Id)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown callback to execute: {payload.Id}", TAG); +#endif + return; + } + try { + _callbacks[payload.Id].Invoke(payload); + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"callback execute failed: {payload.Id}, error: {e}", TAG); +#endif + } + CancelRequest(payload.Id); + } + + /// + /// Subscribe callback on command + /// + /// Command name + /// Callback for command + public void AddCommand(string command, Action callback) { + if (_commands.TryGetValue(command, out var list)) { + list.Add(callback); + _commands[command] = list; + } else { + list = new List>(); + list.Add(callback); + _commands.Add(command, list); + } + } + + /// + /// Unsubscribe callback from command + /// If callback is null -> clear all of them + /// + /// Command name + /// Callback for command + public void CancelCommand(string command, Action callback) { + if (!_commands.ContainsKey(command)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown command to unsubscribe: {command}", TAG); +#endif + return; + } + if (callback == null) { + _commands[command].Clear(); + } else { + var list = _commands[command]; + for (var i = list.Count - 1; i >= 0; i--) { + if (list[i].Equals(callback)) { + list.RemoveAt(i); + break; + } + _commands[command] = list; + } + } + } + + /// + /// Exec callback on command + /// + /// Data for command + void InvokeCommand(PayloadData payload) { + if (!_commands.ContainsKey(payload.Name)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown command to execute: {payload.Name}", TAG); +#endif + return; + } + var list = _commands[payload.Name]; + foreach (var action in list) { + try { + action.Invoke(payload); + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"command execute failed: {payload.Name}, error: {e}", TAG); +#endif + } + } + } + + /// + /// Subscribe to request from server that wait response + /// + /// Request name + /// Callback on RPC + public void AddOnRequest(string request, Action callback) { + if (_requests.ContainsKey(request)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"request already exists: {request}, method: {_requests[request].Method}", TAG); +#endif + } else { + _requests.Add(request, callback); + } + } + + /// + /// Unsubscribe from request from server that wait response + /// + /// Request name + public void CancelOnRequest(string request) { + if (!_requests.ContainsKey(request)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown request to cancel: {request}", TAG); +#endif + return; + } + _requests.Remove(request); + } + + /// + /// Exec callback for RPC from server + /// + /// Request data + public void InvokeOnRequest(PayloadData payload) { + if (!_requests.ContainsKey(payload.Name)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown request to execute: {payload.Name}", TAG); +#endif + return; + } + try { + _requests[payload.Name].Invoke(payload); + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"request execute failed: {payload.Name}, error: {e}", TAG); +#endif + } + } + + /// + /// Send ping + /// + void Heartbeat() { +#if SHARDY_DEBUG + Logger.Info("-> heartbeat"); +#endif + _protocol.Heartbeat(); + } + + /// + /// Send handshake + /// + /// Data to handshake + public void Handshake(byte[] data) { +#if SHARDY_DEBUG + Logger.Info("-> handshake"); +#endif + _protocol.Handshake(data); + } + + /// + /// Send acknowledge + /// + /// Data to acknowledge + public void Acknowledge(byte[] data) { +#if SHARDY_DEBUG + Logger.Info("-> acknowledge"); +#endif + _protocol.Acknowledge(data); + } + + /// + /// Disconnect from server + /// + public void Disconnect() { +#if SHARDY_DEBUG + Logger.Info("-> disconnect"); +#endif + _protocol.Disconnect(); + } + + /// + /// Send command (event) to server with params + /// + /// Command name + /// Payload data + public void Command(string command, byte[] data) { +#if SHARDY_DEBUG + Logger.Info($"-> command: {command}"); +#endif + var payload = Payload.Encode(_serializer, PayloadType.Command, command, 0, data, ""); + _protocol.Send(payload); + } + + /// + /// Send request to server and wait response + /// + /// Request name + /// Payload data + /// Answer from server + /// Request id + public int Request(string request, byte[] data, Action callback) { +#if SHARDY_DEBUG + Logger.Info($"-> request: {_counter}.{request}"); +#endif + var payload = Payload.Encode(_serializer, PayloadType.Request, request, _counter, data, ""); + AddRequest(_counter, request, data, callback); + _protocol.Send(payload); + _counter++; + return _counter; + } + + /// + /// Send response on request from server + /// + /// Request data + /// Data + public void Response(PayloadData request, byte[] data = null) { +#if SHARDY_DEBUG + Logger.Info($"-> response: {request.Id}.{request.Name}"); +#endif + var payload = Payload.Encode(_serializer, PayloadType.Response, request.Name, request.Id, data, ""); + _protocol.Send(payload); + } + + /// + /// Send error on request from server + /// + /// Request data + /// Error message or code + /// Data + public void Error(PayloadData request, string error, byte[] data = null) { +#if SHARDY_DEBUG + Logger.Info($"-> error: {request.Id}.{request.Name}, error: {error}"); +#endif + var payload = Payload.Encode(_serializer, PayloadType.Response, request.Name, request.Id, data, error); + _protocol.Send(payload); + } + + /// + /// Clear all events + /// + public void Clear() { + _cancellation.Cancel(); + _names.Clear(); + _callbacks.Clear(); + _timeouts.Clear(); + _commands.Clear(); + _requests.Clear(); + _pulse?.Clear(); + } + + /// + /// Process data from protocol + /// + /// Block type and possible data + void OnBlock(BlockData block) { +#if SHARDY_DEBUG_RAW + Logger.Info($"block: {block.Type}, data: {Utils.DataToDebug(block.Body)}", TAG); +#endif + switch (block.Type) { + case BlockType.Heartbeat: + OnHeartbeat(); + break; + case BlockType.Kick: + OnKick(block); + break; + case BlockType.HandshakeAcknowledgement: + OnAcknowledgement(block); + break; + case BlockType.Data: + var payload = Payload.Decode(_serializer, block.Body); + if (Payload.Check(payload)) { + OnPayload(payload); + } else { +#if SHARDY_DEBUG_RAW + Logger.Warning($"invalid payload: {payload}", TAG); +#endif + } + break; + default: +#if SHARDY_DEBUG_RAW + Logger.Warning($"not implemented block type: {block.Type}", TAG); +#endif + break; + } + } + + /// + /// Process payload with commands/request/responses + /// When received data, send heartbeat for ok + /// + /// payload Decoded payload data + void OnPayload(PayloadData payload) { + _pulse.Reset(); + Heartbeat(); + switch (payload.Type) { + case PayloadType.Command: +#if SHARDY_DEBUG + Logger.Info($"<- command: {payload.Name}, data: {Utils.DataToDebug(payload.Data)}"); +#endif + InvokeCommand(payload); + break; + case PayloadType.Request: +#if SHARDY_DEBUG + Logger.Info($"<- request: {payload.Id}.{payload.Name}, data: {Utils.DataToDebug(payload.Data)}"); +#endif + InvokeOnRequest(payload); + break; + case PayloadType.Response: +#if SHARDY_DEBUG + if (string.IsNullOrEmpty(payload.Error)) { + Logger.Info($"<- response: {payload.Id}.{payload.Name}, data: {Utils.DataToDebug(payload.Data)}"); + } else { + Logger.Info($"<- error: {payload.Id}.{payload.Name}, error: {payload.Error}, data: {Utils.DataToDebug(payload.Data)}"); + } +#endif + InvokeRequest(payload); + break; + default: + break; + } + } + + /// + /// Event from protocol when connection closed + /// + void OnClose() { +#if SHARDY_DEBUG + Logger.Info("<- disconnect"); +#endif + Clear(); + OnDisconnect(_disconnectReason); + } + + /// + /// Process acknowledgement + /// + /// Acknowledgement data + void OnAcknowledgement(BlockData block) { +#if SHARDY_DEBUG + Logger.Info("<- acknowledge"); +#endif + _pulse.Reset(); + var state = _validator.VerifyAcknowledgement(block.Body); +#if SHARDY_DEBUG_RAW + Logger.Info($"acknowledgement data: {Utils.DataToDebug(block.Body)}, validation state: {state}", TAG); +#endif + if (state == ValidatorState.Success) { + Acknowledge(_validator.Acknowledgement(block.Body)); +#if SHARDY_DEBUG + Logger.Info("ready to work"); +#endif + OnReady(); + } else { + _disconnectReason = DisconnectReason.Handshake; + Disconnect(); + } + } + + /// + /// Process heartbeat from server + /// + void OnHeartbeat() { +#if SHARDY_DEBUG + Logger.Info("<- heartbeat"); +#endif + _pulse.Reset(); + } + + /// + /// Process kick + /// + /// Kick reason data + void OnKick(BlockData block) { + int.TryParse(Utils.DataToString(block.Body), out var index); + _disconnectReason = (DisconnectReason)index; +#if SHARDY_DEBUG + Logger.Info($"<- kick: {_disconnectReason}"); +#endif + _pulse.Reset(); + } + + /// + /// No answer from connection + /// + void OnPulse() { +#if SHARDY_DEBUG + Logger.Info("pulse timeout, send heartbeat"); +#endif + Heartbeat(); + } + + /// + /// Destroy all + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + Clear(); + _protocol.Destroy(); + } + } +} \ No newline at end of file diff --git a/Runtime/Commander.cs.meta b/Runtime/Commander.cs.meta new file mode 100644 index 0000000..b33ee5b --- /dev/null +++ b/Runtime/Commander.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 195c752b89e9041c9afcebe7fe269a3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Connection.cs b/Runtime/Connection.cs new file mode 100644 index 0000000..6fece94 --- /dev/null +++ b/Runtime/Connection.cs @@ -0,0 +1,364 @@ +using System; +using System.Net.Sockets; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; +#if UNITY_IOS +using System.Runtime.InteropServices; +#endif + +namespace Shardy { + + /// + /// Common connection class + /// + public class Connection { + + /// + /// Log tag + /// + const string TAG = "CONNECTION"; + +#if UNITY_WEBGL && !UNITY_EDITOR + /// + /// Cached websocket for WebGL + /// + WebSocket _webglsocket = null; +#else + /// + /// Cached websocket + /// + ClientWebSocket _websocket = null; +#endif + + /// + /// Cached socket + /// + Socket _tcpsocket = null; + + /// + /// Received buffer array + /// + readonly byte[] _received = null; + + /// + /// Connection transport type + /// + readonly TransportType _type = TransportType.Tcp; + + /// + /// Cached transport data + /// + ReceivedData _data = new ReceivedData(); + + /// + /// Cancellation token source + /// + CancellationTokenSource _cancellation = null; + + /// + /// Used flag + /// + bool _isUsed = false; + +#if UNITY_IOS + /// + /// Check and convert IP to IPv6 on iOS + /// + [DllImport("__Internal")] + static extern string CheckIPv6(string host); +#endif + + /// + /// Create new connection + /// + /// Transport type + /// Buffer size + public Connection(TransportType type, int size) { + _type = type; +#if SHARDY_DEBUG_RAW + Logger.Info($"new connection: {_type}", TAG); +#endif + _received = new byte[size]; + CreateSocket(); + } + + /// + /// Create socket instance + /// + void CreateSocket() { + _cancellation = new CancellationTokenSource(); + switch (_type) { + case TransportType.Tcp: + _tcpsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + _webglsocket = new WebSocket(); + _webglsocket.OnError += OnWebSocketError; + _webglsocket.OnClose += OnWebSocketClose; +#else + _websocket = new ClientWebSocket(); +#endif + break; + default: + break; + } + } + + /// + /// Check connection to host + /// + public bool IsConnected { + get { + return _type switch { + TransportType.Tcp => _tcpsocket.Connected, +#if UNITY_WEBGL && !UNITY_EDITOR + TransportType.WebSocket => _webglsocket.State == WebSocketStateCode.Open, +#else + TransportType.WebSocket => _websocket.State == WebSocketState.Open, +#endif + _ => false, + }; + } + } + + /// + /// Open connection + /// + /// Host to connect + /// Port to connect + public async Task Open(string host, int port) { + if (_isUsed) { + DeleteSocket(); + CreateSocket(); + } else { + _isUsed = true; + } + try { +#if UNITY_IOS && !UNITY_EDITOR + var ipv6 = CheckIPv6(host); + if (!string.IsNullOrEmpty(ipv6) && Socket.OSSupportsIPv6) { + host = ipv6; + } + _tcpsocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); +#endif + switch (_type) { + case TransportType.Tcp: +#if SHARDY_DEBUG + Logger.Info($"-> connect to {host}:{port}"); +#endif + await _tcpsocket.ConnectAsync(host, port).WithCancellation(_cancellation.Token); + break; + case TransportType.WebSocket: + var url = $"ws://{host}:{port}"; +#if SHARDY_DEBUG + Logger.Info($"-> connect to {url}"); +#endif +#if UNITY_WEBGL && !UNITY_EDITOR + await _webglsocket.Connect(url).WithCancellation(_cancellation.Token); +#else + await _websocket.ConnectAsync(new Uri(url), CancellationToken.None).WithCancellation(_cancellation.Token); ; +#endif + break; + default: + break; + } + return true; + } catch (OperationCanceledException) { +#if SHARDY_DEBUG_RAW + Logger.Info("open operation canceled", TAG); +#endif + return false; + } catch (SocketException e) { + if (e.SocketErrorCode == SocketError.ConnectionRefused) { +#if SHARDY_DEBUG_RAW + Logger.Info("open socket refused", TAG); +#endif + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"open socket failed: {e}", TAG); +#endif + } + return false; + } catch (WebSocketException e) { + if (e.GetBaseException() is SocketException exception) { + if (exception.SocketErrorCode == SocketError.ConnectionRefused) { +#if SHARDY_DEBUG_RAW + Logger.Info("open websocket refused", TAG); +#endif + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"open websocket as socket failed: {e}", TAG); +#endif + } + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"open websocket failed: {e}", TAG); +#endif + } + return false; + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"open failed: {e}", TAG); +#endif + return false; + } + } + + /// + /// Close connection + /// + public void Close() { + switch (_type) { + case TransportType.Tcp: + if (_tcpsocket.Connected) { + _tcpsocket.Shutdown(SocketShutdown.Both); + _tcpsocket.Close(); + } + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + if (_webglsocket.State == WebSocketStateCode.Open) { + _webglsocket.Close(WebSocketCloseCode.Normal); + } +#else + switch (_websocket.State) { + case WebSocketState.Open: + case WebSocketState.CloseSent: + case WebSocketState.CloseReceived: + _websocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); + break; + default: + break; + } +#endif + break; + default: + break; + } + } + + /// + /// Send data to socket + /// + /// Data to send + public async Task Send(byte[] buffer) { + switch (_type) { + case TransportType.Tcp: + await _tcpsocket.SendAsync(buffer, SocketFlags.None).WithCancellation(_cancellation.Token); + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + await _webglsocket.Send(buffer).WithCancellation(_cancellation.Token); +#else + await _websocket.SendAsync(buffer, WebSocketMessageType.Binary, true, CancellationToken.None).WithCancellation(_cancellation.Token); +#endif + break; + default: + break; + } + } + + /// + /// Receive data from socket + /// + public async Task Receive() { + switch (_type) { + case TransportType.Tcp: + _data.Length = await _tcpsocket.ReceiveAsync(_received, SocketFlags.None).WithCancellation(_cancellation.Token); + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + _data.Length = await _webglsocket.Receive(_received).WithCancellation(_cancellation.Token); +#else + var result = await _websocket.ReceiveAsync(_received, CancellationToken.None).WithCancellation(_cancellation.Token); + _data.Length = (result.MessageType == WebSocketMessageType.Close) ? 0 : result.Count; +#endif + break; + default: + break; + } + _data.Body = _received; + return _data; + } + + /// + /// Cancel operations + /// + public void Cancel() { + _cancellation.Cancel(); + } + +#if UNITY_WEBGL && !UNITY_EDITOR + /// + /// Callback on webglsocket error + /// + /// Websocket error code + void OnWebSocketError(WebSocketErrorCode code) { +#if SHARDY_DEBUG_RAW + Logger.Error($"webgl error: {code}", TAG); +#endif + } + + /// + /// Callback on webglsocket close + /// + /// Websocket close code + void OnWebSocketClose(WebSocketCloseCode code) { +#if SHARDY_DEBUG_RAW + Logger.Error($"webgl close: {code}", TAG); +#endif + Cancel(); + } +#endif + + /// + /// Delete socket instance + /// + void DeleteSocket() { + try { + _cancellation.Dispose(); + switch (_type) { + case TransportType.Tcp: + _tcpsocket.Dispose(); + _tcpsocket = null; + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + WebSocketManager.Destroy(_webglsocket.Id); + _webglsocket = null; +#else + _websocket.Dispose(); + _websocket = null; +#endif + break; + default: + break; + } + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"delete failed: {e}", TAG); +#endif + } + } + + /// + /// Destroy connection + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + try { + Cancel(); + Close(); + DeleteSocket(); + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"destroy failed: {e}", TAG); +#endif + } + } + } +} \ No newline at end of file diff --git a/Runtime/Connection.cs.meta b/Runtime/Connection.cs.meta new file mode 100644 index 0000000..017bb81 --- /dev/null +++ b/Runtime/Connection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5ad515ebacc047d8897007f03214fed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DisconnectReason.cs b/Runtime/DisconnectReason.cs new file mode 100644 index 0000000..5210bf2 --- /dev/null +++ b/Runtime/DisconnectReason.cs @@ -0,0 +1,33 @@ +namespace Shardy { + + /// + /// Disconnect reasons + /// + public enum DisconnectReason { + + /// + /// Normal disconnect + /// + Normal, + + /// + /// Have no answer on ping command + /// + Timeout, + + /// + /// Handshake validation failed + /// + Handshake, + + /// + /// Server is closed` + /// + ServerDown, + + /// + /// Some error occurs + /// + Unknown + } +} \ No newline at end of file diff --git a/Runtime/DisconnectReason.cs.meta b/Runtime/DisconnectReason.cs.meta new file mode 100644 index 0000000..375e3a3 --- /dev/null +++ b/Runtime/DisconnectReason.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa4f5efaa9d4e45c69769a81b1856d68 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ISerializer.cs b/Runtime/ISerializer.cs new file mode 100644 index 0000000..8304ed4 --- /dev/null +++ b/Runtime/ISerializer.cs @@ -0,0 +1,23 @@ +namespace Shardy { + + /// + /// Serializer interface, uses in Payload + /// + public interface ISerializer { + + /// + /// Serialize data to byte array + /// + /// Target data + /// Encoded data + byte[] Encode(PayloadData body); + + /// + /// Deserialize data + /// + /// Encoded data + /// Data to use + PayloadData Decode(byte[] body); + + } +} \ No newline at end of file diff --git a/Runtime/ISerializer.cs.meta b/Runtime/ISerializer.cs.meta new file mode 100644 index 0000000..6cdfab8 --- /dev/null +++ b/Runtime/ISerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0c5ab361eab34fa3847f941f64280f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/IValidator.cs b/Runtime/IValidator.cs new file mode 100644 index 0000000..1524687 --- /dev/null +++ b/Runtime/IValidator.cs @@ -0,0 +1,30 @@ +namespace Shardy { + + /// + /// Handshake interface for client-server validation + /// + public interface IValidator { + + /// + /// Validate acknowledgement data + /// + /// Data for validate + /// Validation result + ValidatorState VerifyAcknowledgement(byte[] body); + + /// + /// Get handshake data for send + /// + /// Data for handshake + /// Data for handshake + byte[] Handshake(byte[] body = null); + + /// + /// Get acknowledgement data for send + /// + /// Data from handshake + /// Data for acknowledge + byte[] Acknowledgement(byte[] body); + + } +} \ No newline at end of file diff --git a/Runtime/IValidator.cs.meta b/Runtime/IValidator.cs.meta new file mode 100644 index 0000000..22ec355 --- /dev/null +++ b/Runtime/IValidator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af4b1517aeb964d3eae4f32f496dbb4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Logger.cs b/Runtime/Logger.cs new file mode 100644 index 0000000..8d6bd02 --- /dev/null +++ b/Runtime/Logger.cs @@ -0,0 +1,119 @@ +using System; +#if !UNITY_WEBGL || UNITY_EDITOR +using UnityEngine; +#endif + +namespace Shardy { + + /// + /// Log colors + /// + public enum LogColor { + Default, + Red, + Orange, + Yellow, + Green, + Blue, + Purple + } + + /// + /// Custom logger + /// + public class Logger { + + /// + /// Date/time format for log + /// + const string DATE_FORMAT = "yyyy-MM-ddTHH:mm:ss.msZ"; + +#if UNITY_WEBGL && !UNITY_EDITOR + /// + /// Mask for log + /// + const string COMMON_MASK = "{0} {1}{2}"; + + /// + /// Mask for label + /// + const string LABEL_MASK = "{0} [{1}] {2}"; +#else + /// + /// Mask for log + /// + const string COMMON_MASK = "{0} {2}{3}"; + + /// + /// Mask for label + /// + const string LABEL_MASK = "{0} [{2}] {3}"; +#endif + + /// + /// Log info + /// + /// Data to log + /// Log label + /// Log color + public static void Info(object data, string label = "", LogColor color = LogColor.Default) { +#if UNITY_WEBGL && !UNITY_EDITOR + Console.WriteLine(string.Format(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), label, data)); +#else + Debug.LogFormat(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), GetColor(color), label, data); +#endif + } + + /// + /// Log warning + /// + /// Data to log + /// Log label + /// Log color + public static void Warning(object data, string label = "", LogColor color = LogColor.Yellow) { +#if UNITY_WEBGL && !UNITY_EDITOR + Console.WriteLine(string.Format(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), label, data)); +#else + Debug.LogWarningFormat(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), GetColor(color), label, data); +#endif + } + + /// + /// Log error + /// + /// Data to log + /// Log label + /// Log color + public static void Error(object data, string label = "", LogColor color = LogColor.Red) { +#if UNITY_WEBGL && !UNITY_EDITOR + Console.WriteLine(string.Format(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), label, data)); +#else + Debug.LogErrorFormat(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), GetColor(color), label, data); +#endif + } + + /// + /// Get mask for log + /// + /// Label for log + static string GetMask(string label) { + return string.IsNullOrEmpty(label) ? COMMON_MASK : LABEL_MASK; + } + + /// + /// Get HEX color for log + /// + /// Color index + static string GetColor(LogColor color) { + return color switch { + LogColor.Red => "#EE4B2B", + LogColor.Orange => "#FFAC1C", + LogColor.Yellow => "#FFFF8F", + LogColor.Green => "#50C878", + LogColor.Blue => "#89CFF0", + LogColor.Purple => "#BF40BF", + _ => "#CCCCCC", + }; + } + } +} \ No newline at end of file diff --git a/Runtime/Logger.cs.meta b/Runtime/Logger.cs.meta new file mode 100644 index 0000000..6a765b0 --- /dev/null +++ b/Runtime/Logger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a15d193bb62e44c18ae6ae1245499f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Payload.cs b/Runtime/Payload.cs new file mode 100644 index 0000000..dfc1b12 --- /dev/null +++ b/Runtime/Payload.cs @@ -0,0 +1,42 @@ +using System; + +namespace Shardy { + + /// + /// Payload encode and decode block data to use in commander + /// + class Payload { + + /// + /// Encode data for transfer + /// + /// Service serializer + /// Type of data + /// Request name + /// Request id + /// Data + /// Data + /// Encoded data + public static byte[] Encode(ISerializer serializer, PayloadType type, string name, int id, byte[] data, string error) { + return serializer.Encode(new PayloadData(type, name, id, data, error)); + } + + /// + /// Decode received block + /// + /// Service serializer + /// Encoded data + /// Payload data to use in commander + public static PayloadData Decode(ISerializer serializer, byte[] data) { + return serializer.Decode(data); + } + + /// + /// Check payload for available type + /// + /// Payload data to check + public static bool Check(PayloadData payload) { + return Enum.IsDefined(typeof(PayloadType), payload.Type); + } + } +} diff --git a/Runtime/Payload.cs.meta b/Runtime/Payload.cs.meta new file mode 100644 index 0000000..869abcd --- /dev/null +++ b/Runtime/Payload.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1750fc2b77e0e4e8da84956166fd3237 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/PayloadData.cs b/Runtime/PayloadData.cs new file mode 100644 index 0000000..93b2c38 --- /dev/null +++ b/Runtime/PayloadData.cs @@ -0,0 +1,52 @@ +using System; + +namespace Shardy { + + /// + /// Payload after decode + /// + [Serializable] + public struct PayloadData { + + /// + /// Type of data + /// + public PayloadType Type; + + /// + /// Command or request name + /// + public string Name; + + /// + /// Request id + /// + public int Id; + + /// + /// Data + /// + public byte[] Data; + + /// + /// Error message or code + /// + public string Error; + + /// + /// Constructor + /// + /// Payload type + /// Command or request name + /// Request id + /// Data + /// Error message or code + public PayloadData(PayloadType type, string name, int id, byte[] data, string error) { + Type = type; + Id = id; + Name = name; + Data = data; + Error = error; + } + } +} \ No newline at end of file diff --git a/Runtime/PayloadData.cs.meta b/Runtime/PayloadData.cs.meta new file mode 100644 index 0000000..a3312a7 --- /dev/null +++ b/Runtime/PayloadData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b59a7b0213a6494bb3f7f66cd76b204 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/PayloadType.cs b/Runtime/PayloadType.cs new file mode 100644 index 0000000..efe2efa --- /dev/null +++ b/Runtime/PayloadType.cs @@ -0,0 +1,23 @@ +namespace Shardy { + + /// + /// Payload type command + /// + public enum PayloadType { + + /// + /// Request and expect answer + /// + Request, + + /// + /// Command without answer, event + /// + Command, + + /// + /// Response on request + /// + Response + } +} \ No newline at end of file diff --git a/Runtime/PayloadType.cs.meta b/Runtime/PayloadType.cs.meta new file mode 100644 index 0000000..125feb2 --- /dev/null +++ b/Runtime/PayloadType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab1f4c0c43865449ba79e044abfd0da9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins.meta b/Runtime/Plugins.meta new file mode 100644 index 0000000..cf18310 --- /dev/null +++ b/Runtime/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8dfe6a07bf5e745928b5fadf94d6eae4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins/WebGL.meta b/Runtime/Plugins/WebGL.meta new file mode 100644 index 0000000..68aab10 --- /dev/null +++ b/Runtime/Plugins/WebGL.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5c846a5a7495141a4851136fd38ffcf6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins/WebGL/websocket.jslib b/Runtime/Plugins/WebGL/websocket.jslib new file mode 100644 index 0000000..1c2d805 --- /dev/null +++ b/Runtime/Plugins/WebGL/websocket.jslib @@ -0,0 +1,317 @@ +/** + * WebSocket library for WebGL + */ +var WebSocketLibrary = { + + /** + * Codes for websocket results + */ + $WebSocketResult: { + Default: 0, + NotFound: -1, + AlreadyConnected: -2, + NotConnected: -3, + AlreadyClosing: -4, + AlreadyClosed: -5, + NotOpened: -6, + CloseFail: -7, + SendFail: -8, + }, + + /** + * Codes for websocket states + */ + $WebSocketState: { + Connecting: 0, + Open: 1, + Closing: 2, + Closed: 3 + }, + + /** + * Manager + */ + $WebSockets: { + list: {}, + counter: 0, + onOpen: null, + onData: null, + onSend: null, + onError: null, + onClose: null, + isDebug: false + }, + + /** + * Get timestamp + * + * @returns Formatted date time + */ + $getTimestamp: function () { + var date = new Date(); + return new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString(); + }, + + /** + * Callback on open connection + */ + wsSetOnOpen: function (callback) { + WebSockets.onOpen = callback; + }, + + /** + * Callback on receive data + */ + wsSetOnData: function (callback) { + WebSockets.onData = callback; + }, + + /** + * Callback on send data + */ + wsSetOnSend: function (callback) { + WebSockets.onSend = callback; + }, + + /** + * Callback on get error + */ + wsSetOnError: function (callback) { + WebSockets.onError = callback; + }, + + /** + * Callback on close + */ + wsSetOnClose: function (callback) { + WebSockets.onClose = callback; + }, + + /** + * Switch on/off debug mode + * + * @param state True or false + */ + wsSetDebug: function (state) { + WebSockets.isDebug = state; + }, + + /** + * Create new websocket connection + * + * @returns Instance id + */ + wsInit: function () { + var id = WebSockets.counter++; + WebSockets.list[id] = { + subprotocols: [], + ws: null + }; + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) init`); + } + return id; + }, + + /** + * Add subprotocol for connection + * + * @param id Instance id + * @param subprotocol Subprotocol + */ + wsAddSubProtocol: function (id, subprotocol) { + var data = UTF8ToString(subprotocol); + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) add subprotocol: ${data}`); + } + WebSockets.list[id].subprotocols.push(data); + }, + + /** + * Remove connection + * + * @param id Instance id + * @returns + */ + wsRemove: function (id) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) remove`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.Default; + }; + if (instance.ws && instance.ws.readyState < WebSocketState.Closing) { + instance.ws.close(); + } + delete WebSockets.list[id]; + return WebSocketResult.Default; + }, + + /** + * Open connection + * + * @param id Instance id + * @param url Url to connect + * @returns Result code + */ + wsConnect: function (id, url) { + var address = UTF8ToString(url); + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) connecting: ${address}`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.NotFound; + } + if (instance.ws !== null) { + return WebSocketResult.AlreadyConnected; + } + instance.ws = new WebSocket(address, instance.subprotocols); + instance.ws.binaryType = 'arraybuffer'; + instance.ws.onopen = function () { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) connected`); + } + if (WebSockets.onOpen) { + Module.dynCall_vi(WebSockets.onOpen, id); + } + }; + instance.ws.onmessage = function (data) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) received data: ${new TextDecoder().decode(data.data)}`); + } + if (WebSockets.onData === null) { + return; + } + if (data.data instanceof ArrayBuffer) { + var dataBuffer = new Uint8Array(data.data); + var buffer = _malloc(dataBuffer.length); + HEAPU8.set(dataBuffer, buffer); + try { + Module.dynCall_viii(WebSockets.onData, id, buffer, dataBuffer.length); + } catch (error) { + console.error(`${getTimestamp()} [WEBSOCKET] (${id}) received failed: ${error.message}`); + } finally { + _free(buffer); + } + } else if (WebSockets.isDebug) { + console.warn(`${getTimestamp()} [WEBSOCKET] (${id}) received not buffer data: ${data.data}`); + } + }; + instance.ws.onerror = function (data) { + if (WebSockets.isDebug) { + var error = (data.code === undefined) ? 'unknown' : data.code; + console.error(`${getTimestamp()} [WEBSOCKET] (${id}) error: ${error}`); + } + if (WebSockets.onError) { + Module.dynCall_vii(WebSockets.onError, id, data.code); + } + }; + instance.ws.onclose = function (data) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) closed: ${data.code}`); + } + if (WebSockets.onClose) { + Module.dynCall_vii(WebSockets.onClose, id, data.code); + } + delete instance.ws; + }; + return WebSocketResult.Default; + }, + + /** + * Close connection + * + * @param id Instance id + * @param code + * @param reason + * @returns Result code + */ + wsClose: function (id, code, reason) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) close: ${code}, reason: ${reason}`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.NotFound; + } + if (!instance.ws) { + return WebSocketResult.NotConnected; + } + if (instance.ws.readyState === WebSocketState.Closing) { + return WebSocketResult.AlreadyClosing; + } + if (instance.ws.readyState === WebSocketState.Closed) { + return WebSocketResult.AlreadyClosed; + } + var result = (reason ? UTF8ToString(reason) : undefined); + try { + instance.ws.close(code, result); + } catch (error) { + console.error(`${getTimestamp()} [WEBSOCKET] (${id}) close error: ${error.message}`); + return WebSocketResult.CloseFail; + } + return WebSocketResult.Default; + }, + + /** + * Send buffer + * @param id Instance id + * @param buffer Data + * @param length Data length + * @returns Result code + */ + wsSend: function (id, data, length) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) send ${length} bytes: ${data}`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.NotFound; + } + if (!instance.ws) { + return WebSocketResult.NotConnected; + } + if (instance.ws.readyState !== WebSocketState.Open) { + return WebSocketResult.NotOpened; + } + try { + instance.ws.send(HEAPU8.buffer.slice(data, data + length)); + } catch (error) { + console.error(`${getTimestamp()} [WEBSOCKET] (${id}) send error: ${error.message}`); + return WebSocketResult.SendFail; + } + if (WebSockets.onSend) { + Module.dynCall_vi(WebSockets.onSend, id); + } + return WebSocketResult.Default; + }, + + /** + * Get connection state + * @param id Instance id + * @returns Result code + */ + wsGetState: function (id) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) get state`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.NotFound; + } + if (instance.ws) { + return instance.ws.readyState; + } else { + return WebSocketState.Closed; + } + } + +}; + +autoAddDeps(WebSocketLibrary, '$WebSockets'); +autoAddDeps(WebSocketLibrary, '$WebSocketResult'); +autoAddDeps(WebSocketLibrary, '$WebSocketState'); +autoAddDeps(WebSocketLibrary, '$getTimestamp'); +mergeInto(LibraryManager.library, WebSocketLibrary); \ No newline at end of file diff --git a/Runtime/Plugins/WebGL/websocket.jslib.meta b/Runtime/Plugins/WebGL/websocket.jslib.meta new file mode 100644 index 0000000..81745ae --- /dev/null +++ b/Runtime/Plugins/WebGL/websocket.jslib.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: d0af6ca4ab28342039b5d382e4887de7 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + WebGL: WebGL + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins/iOS.meta b/Runtime/Plugins/iOS.meta new file mode 100644 index 0000000..bf488ef --- /dev/null +++ b/Runtime/Plugins/iOS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e79797a38127f4967bb79f15ac6c123b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins/iOS/IPv6.mm b/Runtime/Plugins/iOS/IPv6.mm new file mode 100644 index 0000000..5e592e2 --- /dev/null +++ b/Runtime/Plugins/iOS/IPv6.mm @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +#define MakeStringCopy(x) (x != NULL && [x isKindOfClass:[NSString class]]) ? strdup([x UTF8String]) : NULL + +extern "C" { + +const char *CheckIPv6(const char *host) { + if (host == nil) { + return NULL; + } + const char *data = "No"; + int n; + struct addrinfo *res; + struct addrinfo *res0; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_DEFAULT; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if ((n = getaddrinfo(host, "http", &hints, &res0)) != 0) { + return NULL; + } + struct sockaddr_in6 *addr6; + NSString *ipv6 = NULL; + char ipbuf[32]; + for (res = res0; res; res = res->ai_next) { + if (res->ai_family == AF_INET6) { + addr6 = (struct sockaddr_in6 *) res->ai_addr; + data = inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, sizeof(ipbuf)); + NSString *temp = [[NSString alloc] initWithCString:(const char *) data encoding:NSASCIIStringEncoding]; + ipv6 = temp; + } else { + ipv6 = NULL; + } + break; + } + freeaddrinfo(res0); + NSString *result = ipv6; + return MakeStringCopy(result); +} + +} diff --git a/Runtime/Plugins/iOS/IPv6.mm.meta b/Runtime/Plugins/iOS/IPv6.mm.meta new file mode 100644 index 0000000..e89f1f6 --- /dev/null +++ b/Runtime/Plugins/iOS/IPv6.mm.meta @@ -0,0 +1,37 @@ +fileFormatVersion: 2 +guid: b7a227195df3b4848a2c16f93a905468 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Protocol.cs b/Runtime/Protocol.cs new file mode 100644 index 0000000..195e490 --- /dev/null +++ b/Runtime/Protocol.cs @@ -0,0 +1,244 @@ +using System; + +namespace Shardy { + + /// + /// Protocol state + /// + enum ProtocolState { + + /// + /// Init state, wait for handshake + /// + Start, + + /// + /// Handshake is in progress + /// + Handshake, + + /// + /// Work state after success handshake + /// + Work, + + /// + /// Protocol closed, any actions ignored + /// + Closed + } + + + /// + /// Protocol to manage all data from transport, and send to connection handlers + /// + class Protocol { + + /// + /// Log tag + /// + const string TAG = "PROTOCOL"; + + /// + /// Data callback + /// + public Action OnBlock = delegate { }; + + /// + /// Disconnect callback + /// + public Action OnDisconnect = delegate { }; + + /// + /// Current protocol state + /// + ProtocolState _state = ProtocolState.Closed; + + /// + /// Current transporter + /// + readonly Transport _transport = null; + + /// + /// Protocol constructor + /// + /// Current connection + public Protocol(Connection connection) { + _transport = new Transport(connection); + _transport.OnData = (data) => OnData(data); + _transport.OnDisconnect = () => OnClose(); + } + + /// + /// Start protocol and transport + /// + public void Start() { + _state = ProtocolState.Start; + _transport.Start(); + } + + /// + /// Send data to transport + /// + /// Type of block data + /// Data for transfer + internal void Dispatch(BlockType type, byte[] body = null) { + if (_state == ProtocolState.Closed) { +#if SHARDY_DEBUG_RAW + Logger.Warning("send data to closed protocol", TAG); +#endif + return; + } + body ??= (new byte[0]); +#if SHARDY_DEBUG_RAW + Logger.Info($"dispatch type: {type}, body: {Utils.DataToDebug(body)}", TAG); +#endif + var data = Block.Encode(type, body); + _transport.Dispatch(data); + } + + /// + /// Send data to connection + /// + /// Serialized command data + public void Send(byte[] body) { +#if SHARDY_DEBUG_RAW + Logger.Info($"send data: {Utils.DataToDebug(body)}", TAG); +#endif + Dispatch(BlockType.Data, body); + } + + /// + /// Send heartbeat to connection + /// + public void Heartbeat() { +#if SHARDY_DEBUG_RAW + Logger.Info("send heartbeat", TAG); +#endif + Dispatch(BlockType.Heartbeat); + } + + /// + /// Send handshake to connection + /// + /// Handshake data + public void Handshake(byte[] body) { +#if SHARDY_DEBUG_RAW + Logger.Info("send handshake", TAG); +#endif + _state = ProtocolState.Handshake; + Dispatch(BlockType.Handshake, body); + } + + /// + /// Send acknowledgement + /// + /// Acknowledge data + public void Acknowledge(byte[] body) { +#if SHARDY_DEBUG_RAW + Logger.Info("send acknowledge", TAG); +#endif + _state = ProtocolState.Work; + Dispatch(BlockType.HandshakeAcknowledgement, body); + } + + /// + /// Disconnect from server + /// + public void Disconnect() { + _state = ProtocolState.Closed; +#if SHARDY_DEBUG_RAW + Logger.Info("disconnect", TAG); +#endif + _transport.Close(); + } + + /// + /// Callback from transport when disconnected + /// + internal void OnClose() { + _state = ProtocolState.Closed; + OnDisconnect(); + } + + /// + /// Decode data to package + /// Select behaviour by package type + /// + /// Buffer bytes array + internal void OnData(byte[] data) { + if (_state == ProtocolState.Closed) { +#if SHARDY_DEBUG_RAW + Logger.Warning("received data to closed protocol", TAG); +#endif + return; + } + var block = Block.Decode(data); + if (!Block.Check(block.Type)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"invalid block type: {block.Type}, state: {_state}", TAG); +#endif + return; + } +#if SHARDY_DEBUG_RAW + Logger.Info($"received block: {block.Type}, data: {Utils.DataToDebug(block.Body)}, state: {_state}", TAG); +#endif + switch (_state) { + case ProtocolState.Start: + if (block.Type == BlockType.Heartbeat) { + OnBlock(block); + } else { + CatchBlockForState(block.Type); + } + break; + case ProtocolState.Work: + switch (block.Type) { + case BlockType.Heartbeat: + case BlockType.Kick: + case BlockType.Data: + OnBlock(block); + break; + default: + CatchBlockForState(block.Type); + break; + } + break; + case ProtocolState.Handshake: + switch (block.Type) { + case BlockType.HandshakeAcknowledgement: + case BlockType.Kick: + OnBlock(block); + break; + default: + CatchBlockForState(block.Type); + break; + } + break; + default: + CatchBlockForState(block.Type); + break; + } + } + + /// + /// Catch and log incorrect situation + /// + /// Block type + void CatchBlockForState(BlockType type) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"invalid block type: {type}, state: {_state}", TAG); +#endif + } + + /// + /// Destroy all + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + _state = ProtocolState.Closed; + _transport.Destroy(); + } + } +} \ No newline at end of file diff --git a/Runtime/Protocol.cs.meta b/Runtime/Protocol.cs.meta new file mode 100644 index 0000000..2bcd576 --- /dev/null +++ b/Runtime/Protocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05073643c2eff400689ddc8f3679e867 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Pulse.cs b/Runtime/Pulse.cs new file mode 100644 index 0000000..6379c35 --- /dev/null +++ b/Runtime/Pulse.cs @@ -0,0 +1,62 @@ +using System; +using System.Threading; + +#pragma warning disable 4014 + +namespace Shardy { + + /// + /// Pulse service for support connection + /// + class Pulse { + + /// + /// Callback + /// + public Action OnPulse = delegate { }; + + /// + /// Cancellation token source + /// + readonly CancellationTokenSource _cancellation = new CancellationTokenSource(); + + /// + /// Checks counter + /// + int _checks = 0; + + /// + /// Constructor + /// + /// Interval to check pulse + public Pulse(float interval) { + Utils.SetTimer(interval, _cancellation, () => CheckPulse()); + } + + /// + /// Pulse checker + /// + public void CheckPulse() { + _checks++; + if (_checks > 1) { + Reset(); + OnPulse(); + } + } + + /// + /// Reset timer when commands received + /// + public void Reset() { + _checks = 0; + } + + /// + /// Stop and switch off service + /// + public void Clear() { + Reset(); + _cancellation.Cancel(); + } + } +} \ No newline at end of file diff --git a/Runtime/Pulse.cs.meta b/Runtime/Pulse.cs.meta new file mode 100644 index 0000000..e2da804 --- /dev/null +++ b/Runtime/Pulse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0df7a1de43fa74a0082f87d7555abd11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ReceivedData.cs b/Runtime/ReceivedData.cs new file mode 100644 index 0000000..eed7a84 --- /dev/null +++ b/Runtime/ReceivedData.cs @@ -0,0 +1,28 @@ +namespace Shardy { + + /// + /// Data received from socket + /// + public struct ReceivedData { + + /// + /// Data length + /// + public int Length; + + /// + /// Data bytes array + /// + public byte[] Body; + + /// + /// Constructor + /// + /// Data for block + /// Data length + public ReceivedData(byte[] body, int length) { + Body = body; + Length = length; + } + } +} \ No newline at end of file diff --git a/Runtime/ReceivedData.cs.meta b/Runtime/ReceivedData.cs.meta new file mode 100644 index 0000000..48c8ce0 --- /dev/null +++ b/Runtime/ReceivedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e038338fdd7174c1d9c61c93390d27b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shardy.asmdef b/Runtime/Shardy.asmdef new file mode 100644 index 0000000..f3565fa --- /dev/null +++ b/Runtime/Shardy.asmdef @@ -0,0 +1,14 @@ +{ + "name": "Shardy", + "rootNamespace": "Shardy", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Runtime/Shardy.asmdef.meta b/Runtime/Shardy.asmdef.meta new file mode 100644 index 0000000..bc3bcaa --- /dev/null +++ b/Runtime/Shardy.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9b891ca15e43e41c6bac338ce42625c8 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Transport.cs b/Runtime/Transport.cs new file mode 100644 index 0000000..c0a4f9d --- /dev/null +++ b/Runtime/Transport.cs @@ -0,0 +1,360 @@ +using System; +using System.Net.WebSockets; + +namespace Shardy { + + /// + /// Transporter state + /// + enum TransportState { + + /// + /// Receive head data + /// + Head, + + /// + /// Receive body data + /// + Body, + + /// + /// Transport is closed, no more data received + /// + Closed + } + + /// + /// Transporter for protocol + /// Manage how data should send and receive to protocol + /// + class Transport { + + /// + /// Log tag + /// + const string TAG = "TRANSPORT"; + + /// + /// Callback to return data to handler + /// + public Action OnData = delegate { }; + + /// + /// Callback to return disconnect state + /// + public Action OnDisconnect = delegate { }; + + /// + /// Current transporter state + /// + TransportState _state = TransportState.Closed; + + /// + /// Common buffer array + /// + byte[] _buffer = null; + + /// + /// Offset to write buffer + /// + int _offset = 0; + + /// + /// Length of current package + /// + int _package = 0; + + /// + /// Current connection + /// + Connection _connection = null; + + /// + /// Constructor + /// + /// Connection instance + public Transport(Connection connection) { + _connection = connection; + } + + /// + /// Start receiving data + /// + public void Start() { + _state = TransportState.Head; + Receive(); + } + + /// + /// Send data to socket + /// + /// Bytes array + public async void Dispatch(byte[] buffer) { + if (!_connection.IsConnected) { +#if SHARDY_DEBUG_RAW + Logger.Warning("try send data with disconnected", TAG); +#endif + return; + } + if (_state != TransportState.Closed) { + try { + await _connection.Send(buffer); + } catch (OperationCanceledException) { +#if SHARDY_DEBUG_RAW + Logger.Info("send operation canceled", TAG); +#endif + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"send failed: {e}", TAG); +#endif + } + } else { +#if SHARDY_DEBUG_RAW + Logger.Warning($"send data when state closed: {Utils.DataToDebug(buffer)}", TAG); +#endif + } + } + + /// + /// Close this transport + /// + public void Close() { + try { + if (_connection != null) { + _connection.Cancel(); + _connection.Close(); + } + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"close failed: {e}", TAG); +#endif + } + } + + /// + /// Begin receive data from socket + /// + public async void Receive() { + if (_state == TransportState.Closed) { +#if SHARDY_DEBUG_RAW + Logger.Warning("received data on closed state", TAG); +#endif + return; + } + ReceivedData data = default; + try { + data = await _connection.Receive(); + } catch (OperationCanceledException) { +#if SHARDY_DEBUG_RAW + Logger.Info("receive operation canceled", TAG); +#endif + ReceiveEnd(); + return; + } catch (WebSocketException e) { + if (e.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely) { +#if SHARDY_DEBUG_RAW + Logger.Info("receive websocket closed prematurely", TAG); +#endif + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"receive websocket failed: {e}", TAG); +#endif + } + ReceiveEnd(); + return; + } catch (Exception e) { + if (e.GetBaseException() is WebSocketException exception) { + if (exception.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely) { +#if SHARDY_DEBUG_RAW + Logger.Info("receive as websocket closed prematurely", TAG); +#endif + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"receive as websocket failed: {e}", TAG); +#endif + } + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"receive failed: {e}", TAG); +#endif + } + ReceiveEnd(); + return; + } + if (!_connection.IsConnected && data.Length > 0) { +#if SHARDY_DEBUG_RAW + Logger.Warning("try receive data with disconnected", TAG); +#endif + return; + } +#if SHARDY_DEBUG_RAW + Logger.Info($"received size: {data.Length}, data: {Utils.DataToDebug(data.Body)}", TAG); +#endif + if (data.Length > 0) { + ProcessData(data.Body, 0, data.Length); + Receive(); + } else { + ReceiveEnd(); + } + } + + /// + /// Actions when receive finished + /// + void ReceiveEnd() { + _state = TransportState.Closed; + Close(); + OnDisconnect(); + } + + /// + /// Detect what to read and read it + /// + /// Data array + /// Offet to read + /// Length to read + internal void ProcessData(byte[] bytes, int offset, int limit) { + switch (_state) { + case TransportState.Head: + ReadHead(bytes, offset, limit); + break; + case TransportState.Body: + ReadBody(bytes, offset, limit); + break; + default: +#if SHARDY_DEBUG_RAW + Logger.Warning($"process bytes on incorrect state: {_state}", TAG); +#endif + break; + } + } + + /// + /// Get package size from head + /// + /// Head buffer + int GetPackageSize(byte[] buffer) { + var result = 0; + for (var i = 1; i < Block.HEAD_SIZE; i++) { + if (i > 1) { + result <<= 8; + } + result += buffer[i]; + } + return result; + } + + /// + /// Read header + /// + /// Data array + /// Offet to read + /// Length to read + /// Correct header or not + bool ReadHead(byte[] bytes, int offset, int limit) { + var length = limit - offset; + var head = new byte[Block.HEAD_SIZE]; + var size = Block.HEAD_SIZE - _offset; + if (length >= size) { + WriteBytes(bytes, offset, size, _offset, head); + _package = GetPackageSize(head); + if (_package < 0) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"invalid package size: {_package}", TAG); +#endif + size = 0; + } + _buffer = new byte[Block.HEAD_SIZE + _package]; + WriteBytes(head, 0, Block.HEAD_SIZE, _buffer); + offset += size; + _offset = Block.HEAD_SIZE; + _state = TransportState.Body; + if (offset <= limit) { + ProcessData(bytes, offset, limit); + } + return true; + } else { + WriteBytes(bytes, offset, length, _offset, head); + _offset += length; + return false; + } + } + + /// + /// Read body + /// + /// Data array + /// Offet to read + /// Length to read + void ReadBody(byte[] bytes, int offset, int limit) { + var length = _package + Block.HEAD_SIZE - _offset; + if ((offset + length) <= limit) { + WriteBytes(bytes, offset, length, _offset, _buffer); + offset += length; + OnData(_buffer); + Reset(); + if (offset < limit) { + ProcessData(bytes, offset, limit); + } + } else { + WriteBytes(bytes, offset, limit - offset, _offset, _buffer); + _offset += limit - offset; + _state = TransportState.Body; + } + } + + /// + /// Reset all data after receive full package + /// + void Reset() { + _offset = 0; + _package = 0; + if (_state != TransportState.Closed) { + _state = TransportState.Head; + } + } + + /// + /// Write to buffer + /// + /// Source array + /// Start offset + /// Length to write + /// Target to write + void WriteBytes(byte[] source, int start, int length, byte[] target) { + WriteBytes(source, start, length, 0, target); + } + + /// Write to buffer + /// + /// Source array + /// Start offset + /// Length to write + /// Offset on target array + /// Target to write + void WriteBytes(byte[] source, int start, int length, int offset, byte[] target) { + for (var i = 0; i < length; i++) { + target[offset + i] = source[start + i]; + } + } + + /// + /// Destroy all + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + _state = TransportState.Closed; + try { + _connection.Destroy(); + _connection = null; + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"destroy failed: {e}", TAG); +#endif + } + } + } +} \ No newline at end of file diff --git a/Runtime/Transport.cs.meta b/Runtime/Transport.cs.meta new file mode 100644 index 0000000..d58f5ad --- /dev/null +++ b/Runtime/Transport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f15005000f27e4050bf9c56e686b5856 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/TransportType.cs b/Runtime/TransportType.cs new file mode 100644 index 0000000..b5d2ad9 --- /dev/null +++ b/Runtime/TransportType.cs @@ -0,0 +1,18 @@ +namespace Shardy { + + /// + /// Type of transport + /// + public enum TransportType { + + /// + /// TCP sockets transport + /// + Tcp, + + /// + /// Websockets transport + /// + WebSocket + } +} \ No newline at end of file diff --git a/Runtime/TransportType.cs.meta b/Runtime/TransportType.cs.meta new file mode 100644 index 0000000..c98a403 --- /dev/null +++ b/Runtime/TransportType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a733b44d06d6f40bc949dc260fff979d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Utils.cs b/Runtime/Utils.cs new file mode 100644 index 0000000..2590cf9 --- /dev/null +++ b/Runtime/Utils.cs @@ -0,0 +1,134 @@ +using System; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Shardy { + + /// + /// Some usefull functions + /// + public static class Utils { + + /// + /// Custom timer for WebGL compatibility + /// + /// Interval for timer, ms + /// Cancellation source + /// Callback on tick + public static async Task SetTimer(float interval, CancellationTokenSource cancellation, Action callback) { + while (!cancellation.IsCancellationRequested) { + await SetDelay(interval); + callback(); + } + } + + /// + /// Make delay + /// Hack to prevent using Task.Delay in WebGL + /// + /// Delay in ms + public static async Task SetDelay(float delay) { + var target = DateTime.Now.AddMilliseconds(delay); + while (DateTime.Now < target) { + await Task.Yield(); + } + } + + /// + /// Extension to add cancellation for task + /// + public static async Task WithCancellation(this Task task, CancellationToken cancellationToken) { + var source = new TaskCompletionSource(); + using (cancellationToken.Register(state => ((TaskCompletionSource)state).TrySetResult(true), source)) { + if (task != await Task.WhenAny(task, source.Task)) { + throw new OperationCanceledException(cancellationToken); + } + } + return task.Result; + } + + /// + /// Extension to add cancellation for task + /// + public static async Task WithCancellation(this Task task, CancellationToken cancellationToken) { + var source = new TaskCompletionSource(); + using (cancellationToken.Register(state => ((TaskCompletionSource)state).TrySetResult(true), source)) { + if (task != await Task.WhenAny(task, source.Task).ConfigureAwait(false)) { + throw new OperationCanceledException(cancellationToken); + } + await task; + } + } + + /// + /// Convert data to string + /// + public static string DataToString(byte[] data) { + return (data == null) ? string.Empty : Encoding.UTF8.GetString(data); + } + +#if SHARDY_DEBUG || SHARDY_DEBUG_RAW + + /// + /// Convert data to log string + /// + public static string DataToDebug(byte[] data) { + return (data == null) ? string.Empty : ToLiteral(Encoding.UTF8.GetString(data)); + } + + /// + /// Escape string for log + /// + /// Input string + static string ToLiteral(string data) { + var literal = new StringBuilder(data.Length); + foreach (var c in data) { + switch (c) { + case '\"': + literal.Append("\\\""); + break; + case '\\': + literal.Append(@"\\"); + break; + case '\0': + literal.Append(@"\0"); + break; + case '\a': + literal.Append(@"\a"); + break; + case '\b': + literal.Append(@"\b"); + break; + case '\f': + literal.Append(@"\f"); + break; + case '\n': + literal.Append(@"\n"); + break; + case '\r': + literal.Append(@"\r"); + break; + case '\t': + literal.Append(@"\t"); + break; + case '\v': + literal.Append(@"\v"); + break; + default: + if (c >= 0x20 && c <= 0x7e) { + literal.Append(c); + } else { + literal.Append(@"\u"); + literal.Append(((int)c).ToString("x4")); + } + break; + } + } + return literal.ToString(); + } + +#endif + + } +} \ No newline at end of file diff --git a/Runtime/Utils.cs.meta b/Runtime/Utils.cs.meta new file mode 100644 index 0000000..12e7761 --- /dev/null +++ b/Runtime/Utils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffe31bde2d4c542dca0c306856360791 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ValidatorState.cs b/Runtime/ValidatorState.cs new file mode 100644 index 0000000..d037178 --- /dev/null +++ b/Runtime/ValidatorState.cs @@ -0,0 +1,18 @@ +namespace Shardy { + + /// + /// Validator state + /// + public enum ValidatorState { + + /// + /// Handshake passed + /// + Success, + + /// + /// Handshake failed + /// + Failed + } +} \ No newline at end of file diff --git a/Runtime/ValidatorState.cs.meta b/Runtime/ValidatorState.cs.meta new file mode 100644 index 0000000..623641a --- /dev/null +++ b/Runtime/ValidatorState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b17c053b8922c4d3fb3434dc532c4489 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/WebSocket.cs b/Runtime/WebSocket.cs new file mode 100644 index 0000000..e5b2900 --- /dev/null +++ b/Runtime/WebSocket.cs @@ -0,0 +1,291 @@ +#if UNITY_WEBGL + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace Shardy { + + /// + /// Condition key for wait callback + /// + enum WaitCondition { + Open, + Send, + Close + } + + /// + /// Websocket state codes + /// + enum WebSocketStateCode { + Connecting, + Open, + Closing, + Closed, + Error + } + + /// + /// Return error codes + /// + enum WebSocketErrorCode { + NotFound = -1, + AlreadyConnected = -2, + NotConnected = -3, + AlreadyClosing = -4, + AlreadyClosed = -5, + NotOpened = -6, + CloseFail = -7, + SendFail = -8, + Unknown = -999 + } + + /// + /// Websocket code for close + /// + enum WebSocketCloseCode { + NotSet = 0, + Normal = 1000, + Away = 1001, + ProtocolError = 1002, + UnsupportedData = 1003, + Undefined = 1004, + NoStatus = 1005, + Abnormal = 1006, + InvalidData = 1007, + PolicyViolation = 1008, + TooBig = 1009, + MandatoryExtension = 1010, + ServerError = 1011, + TlsHandshakeFailure = 1015 + } + + /// + /// WebSocket class for WebGL using + /// + class WebSocket { + + /// + /// Log tag + /// + const string TAG = "WEBSOCKET"; + + /// + /// Delay, ms + /// + const float DELAY = 10f; + + /// + /// Callback on socket open + /// + public Action OnOpen = delegate { }; + + /// + /// Callback on socket send + /// + public Action OnSend = delegate { }; + + /// + ///Callback on message receive + /// + public Action OnData = delegate { }; + + /// + /// Callback on error receive + /// + public Action OnError = delegate { }; + + /// + /// Callback on close socket + /// + public Action OnClose = delegate { }; + + /// + /// Connect to socket + /// + [DllImport("__Internal")] + public static extern int wsConnect(int id, string url); + + /// + /// Close socket + /// + [DllImport("__Internal")] + public static extern int wsClose(int id, int code, string reason); + + /// + /// Send buffer to socket + /// + [DllImport("__Internal")] + public static extern int wsSend(int id, byte[] data, int length); + + /// + /// Get current state + /// + [DllImport("__Internal")] + public static extern int wsGetState(int id); + + /// + /// Dict for check waitable vars + /// + readonly Dictionary _conditions = new Dictionary(3); + + /// + /// Received buffer + /// + List _buffer = new List(); + + /// + /// Current socket instance id + /// + protected int _id = -1; + + /// + /// Create websocket + /// + public WebSocket() { + _id = WebSocketManager.Add(this); + Subscribe(); + } + + /// + /// Create websocket + /// + /// Optional subprotocol + public WebSocket(string subprotocol) { + _id = WebSocketManager.Add(this); + WebSocketManager.wsAddSubProtocol(_id, subprotocol); + Subscribe(); + } + + /// + /// Create websocket + /// + /// Optional subprotocols list + public WebSocket(List subprotocols) { + _id = WebSocketManager.Add(this); + foreach (var subprotocol in subprotocols) { + WebSocketManager.wsAddSubProtocol(_id, subprotocol); + } + Subscribe(); + } + + /// + /// Subscribe for inner callbacks + /// + void Subscribe() { + _conditions[WaitCondition.Open] = false; + _conditions[WaitCondition.Send] = false; + _conditions[WaitCondition.Close] = false; + OnOpen += () => _conditions[WaitCondition.Open] = true; + OnSend += () => _conditions[WaitCondition.Send] = true; + OnClose += (WebSocketCloseCode code) => _conditions[WaitCondition.Close] = true; + OnData += (byte[] data, int length) => { + _buffer.Add(new ReceivedData(data, length)); + }; + } + + /// + /// Remove websocket + /// + ~WebSocket() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + WebSocketManager.wsRemove(_id); + } + + /// + /// Current socket id + /// + public int Id { + get { + return _id; + } + } + + /// + /// Current state + /// + public WebSocketStateCode State { + get { + var state = wsGetState(_id); + return state switch { + 0 => WebSocketStateCode.Connecting, + 1 => WebSocketStateCode.Open, + 2 => WebSocketStateCode.Closing, + 3 => WebSocketStateCode.Closed, + _ => WebSocketStateCode.Error, + }; + } + } + + /// + /// Check return code state on error + /// + /// Return state + /// Has error or not + bool CheckState(int state) { + if (state < 0) { +#if SHARDY_DEBUG + var error = Enum.IsDefined(typeof(WebSocketErrorCode), state) ? (WebSocketErrorCode)state : WebSocketErrorCode.Unknown; + Logger.Error($"state error: {error}", TAG); +#endif + return false; + } + return true; + } + + /// + /// Connect to server + /// + public async Task Connect(string url) { + var state = wsConnect(_id, url); + while (!_conditions[WaitCondition.Open]) { + await Utils.SetDelay(DELAY); + } + return CheckState(state); + } + + /// + /// Close connection + /// + /// Close code + /// Reason + public bool Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null) { + var state = wsClose(_id, (int)code, reason); + return CheckState(state); + } + + /// + /// Send data as buffer + /// + /// Array of bytes + public async Task Send(byte[] data) { + var state = wsSend(_id, data, data.Length); + while (!_conditions[WaitCondition.Send]) { + await Utils.SetDelay(DELAY); + } + _conditions[WaitCondition.Send] = false; + return CheckState(state); + } + + /// + /// Receive data from socket + /// + /// Buffer to write + /// Received length + public async Task Receive(byte[] buffer) { + while (_buffer.Count == 0) { + await Utils.SetDelay(DELAY); + } + var data = _buffer[0]; + _buffer.RemoveAt(0); + Array.Copy(data.Body, 0, buffer, 0, data.Length); + return data.Length; + } + } +} + +#endif \ No newline at end of file diff --git a/Runtime/WebSocket.cs.meta b/Runtime/WebSocket.cs.meta new file mode 100644 index 0000000..aacc090 --- /dev/null +++ b/Runtime/WebSocket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4dbdc96924f6748ceba47023cd6b2600 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/WebSocketManager.cs b/Runtime/WebSocketManager.cs new file mode 100644 index 0000000..b10f5e8 --- /dev/null +++ b/Runtime/WebSocketManager.cs @@ -0,0 +1,219 @@ +#if UNITY_WEBGL + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using AOT; + +namespace Shardy { + + /// + /// Websocket manager for WebGL + /// + static class WebSocketManager { + + /// + /// List of websockets + /// + static readonly Dictionary _list = new Dictionary(); + + /// + /// On open socket delegate + /// + /// Instance id + public delegate void OnOpen(int id); + + /// + /// On send to socket delegate + /// + /// Instance id + public delegate void OnSend(int id); + + /// + /// On data receive delegate + /// + /// Instance id + /// Pointer to message + /// Data length + public delegate void OnData(int id, IntPtr message, int length); + + /// + /// On error receive delegate + /// + /// Instance id + /// Error code + public delegate void OnError(int id, int code); + + /// + /// On close socket delegate + /// + /// Instance id + /// Close code + public delegate void OnClose(int id, int code); + + /// + /// Set on/off debug mode + /// + [DllImport("__Internal")] + public static extern int wsSetDebug(bool value); + + /// + /// Create new websocket instance + /// + [DllImport("__Internal")] + public static extern int wsInit(); + + /// + /// Remove websocket + /// + [DllImport("__Internal")] + public static extern void wsRemove(int id); + + /// + /// Add subprotocol + /// + [DllImport("__Internal")] + public static extern int wsAddSubProtocol(int id, string subprotocol); + + /// + /// Set on open callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnOpen(OnOpen callback); + + /// + /// Set on send callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnSend(OnSend callback); + + /// + /// Set on data receive callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnData(OnData callback); + + /// + /// Set on error receive callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnError(OnError callback); + + /// + /// Set on close callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnClose(OnClose callback); + + /// + /// Flag to check initialized + /// + static bool _isInitialized = false; + + /// + /// Set debug mode + /// + public static void SetDebug(bool value) { + wsSetDebug(value); + } + + /// + /// Set callbacks + /// + public static void Init() { + if (!_isInitialized) { + wsSetOnOpen(OnOpenEvent); + wsSetOnSend(OnSendEvent); + wsSetOnData(OnDataEvent); + wsSetOnError(OnErrorEvent); + wsSetOnClose(OnCloseEvent); + _isInitialized = true; + } + } + + /// + /// Add new socket + /// + /// Websocket instance + /// Id + public static int Add(WebSocket socket) { + var id = wsInit(); + _list.Add(id, socket); + return id; + } + + /// + /// Remove websocket instance + /// + /// Instance id + public static void Destroy(int id) { + if (_list.ContainsKey(id)) { + _list.Remove(id); + wsRemove(id); + } + } + + /// + /// On open event from jslib + /// + /// Instance id + [MonoPInvokeCallback(typeof(OnOpen))] + public static void OnOpenEvent(int id) { + if (_list.ContainsKey(id)) { + _list[id].OnOpen(); + } + } + + /// + /// On send event from jslib + /// + /// Instance id + [MonoPInvokeCallback(typeof(OnSend))] + public static void OnSendEvent(int id) { + if (_list.ContainsKey(id)) { + _list[id].OnSend(); + } + } + + /// + /// On data receive event from jslib + /// + /// Instance id + [MonoPInvokeCallback(typeof(OnData))] + public static void OnDataEvent(int id, IntPtr message, int length) { + if (_list.ContainsKey(id)) { + var data = new byte[length]; + Marshal.Copy(message, data, 0, length); + _list[id].OnData(data, length); + } + } + + /// + /// On error receive event from jslib + /// + /// Instance id + /// Error code + [MonoPInvokeCallback(typeof(OnError))] + public static void OnErrorEvent(int id, int code) { + if (_list.ContainsKey(id)) { + var error = Enum.IsDefined(typeof(WebSocketErrorCode), code) ? (WebSocketErrorCode)code : WebSocketErrorCode.Unknown; + _list[id].OnError(error); + } + } + + /// + /// On close event from jslib + /// + /// Instance id + /// Close code + [MonoPInvokeCallback(typeof(OnClose))] + public static void OnCloseEvent(int id, int code) { + if (_list.ContainsKey(id)) { + var result = Enum.IsDefined(typeof(WebSocketCloseCode), code) ? (WebSocketCloseCode)code : WebSocketCloseCode.Undefined; + _list[id].OnClose(result); + } + } + } +} + +#endif \ No newline at end of file diff --git a/Runtime/WebSocketManager.cs.meta b/Runtime/WebSocketManager.cs.meta new file mode 100644 index 0000000..6fc5841 --- /dev/null +++ b/Runtime/WebSocketManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7ab03736437e4580866c7a13004ee9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo.meta b/Samples~/Demo.meta new file mode 100644 index 0000000..1937e4b --- /dev/null +++ b/Samples~/Demo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d70a34e1790ec4fb6ba0568b3faf4061 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scenes.meta b/Samples~/Demo/Scenes.meta new file mode 100644 index 0000000..9e9ab46 --- /dev/null +++ b/Samples~/Demo/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 49ae41e15900a4725956bbee5c3d4533 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scenes/Demo.unity b/Samples~/Demo/Scenes/Demo.unity new file mode 100644 index 0000000..b9badd5 --- /dev/null +++ b/Samples~/Demo/Scenes/Demo.unity @@ -0,0 +1,6314 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &86744315 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 86744318} + - component: {fileID: 86744317} + - component: {fileID: 86744316} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &86744316 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 86744315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &86744317 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 86744315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &86744318 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 86744315} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &87791714 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 87791715} + - component: {fileID: 87791717} + - component: {fileID: 87791716} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &87791715 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87791714} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 876135628} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &87791716 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87791714} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Subscribe + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &87791717 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87791714} + m_CullTransparentMesh: 1 +--- !u!1 &115949711 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 115949713} + - component: {fileID: 115949715} + - component: {fileID: 115949714} + - component: {fileID: 115949712} + m_Layer: 5 + m_Name: PortInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &115949712 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 115949711} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 115949714} + m_TextViewport: {fileID: 322493275} + m_TextComponent: {fileID: 2097740590} + m_Placeholder: {fileID: 2098744277} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 2 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 4 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 2 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: 3000 + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!224 &115949713 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 115949711} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 322493275} + m_Father: {fileID: 207479225} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 144, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &115949714 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 115949711} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &115949715 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 115949711} + m_CullTransparentMesh: 1 +--- !u!1 &150526394 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 150526395} + - component: {fileID: 150526398} + - component: {fileID: 150526397} + - component: {fileID: 150526396} + m_Layer: 5 + m_Name: OffRequestButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &150526395 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 150526394} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 448535453} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &150526396 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 150526394} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 150526397} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: UnsubscribeRequest + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &150526397 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 150526394} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &150526398 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 150526394} + m_CullTransparentMesh: 1 +--- !u!1 &185570083 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 185570084} + - component: {fileID: 185570087} + - component: {fileID: 185570086} + - component: {fileID: 185570085} + m_Layer: 5 + m_Name: LogScroll + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &185570084 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 185570083} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1461012000} + - {fileID: 396431563} + m_Father: {fileID: 1917894912} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 32} + m_SizeDelta: {x: -64, y: 224} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &185570085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 185570083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 1561090812} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 1461012000} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 396431564} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &185570086 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 185570083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &185570087 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 185570083} + m_CullTransparentMesh: 1 +--- !u!1 &207479224 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 207479225} + - component: {fileID: 207479226} + m_Layer: 5 + m_Name: HostPort + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &207479225 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207479224} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1926762628} + - {fileID: 798780212} + - {fileID: 1189404154} + - {fileID: 115949713} + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &207479226 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207479224} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 3 + m_Spacing: 0 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 0 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &322493274 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 322493275} + - component: {fileID: 322493276} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &322493275 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 322493274} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2098744280} + - {fileID: 2097740592} + m_Father: {fileID: 115949713} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &322493276 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 322493274} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &396431562 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 396431563} + - component: {fileID: 396431566} + - component: {fileID: 396431565} + - component: {fileID: 396431564} + m_Layer: 5 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &396431563 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 396431562} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 444005365} + m_Father: {fileID: 185570084} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 48, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &396431564 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 396431562} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1809996613} + m_HandleRect: {fileID: 1809996612} + m_Direction: 2 + m_Value: 0.52008855 + m_Size: 0.074666664 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &396431565 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 396431562} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &396431566 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 396431562} + m_CullTransparentMesh: 1 +--- !u!1 &444005364 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 444005365} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &444005365 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 444005364} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1809996612} + m_Father: {fileID: 396431563} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &448535452 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 448535453} + - component: {fileID: 448535455} + - component: {fileID: 448535454} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &448535453 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 448535452} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 150526395} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &448535454 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 448535452} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Off request + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &448535455 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 448535452} + m_CullTransparentMesh: 1 +--- !u!1 &454989673 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 454989674} + - component: {fileID: 454989675} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &454989674 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 454989673} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 569754090} + - {fileID: 504131352} + m_Father: {fileID: 1041758959} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &454989675 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 454989673} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &504131351 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 504131352} + - component: {fileID: 504131354} + - component: {fileID: 504131353} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &504131352 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504131351} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 454989674} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &504131353 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504131351} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &504131354 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504131351} + m_CullTransparentMesh: 1 +--- !u!1 &519420028 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 519420032} + - component: {fileID: 519420031} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!20 &519420031 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 1 + m_AllowMSAA: 0 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &519420032 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &539258973 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 539258974} + - component: {fileID: 539258975} + m_Layer: 0 + m_Name: Scripts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &539258974 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 539258973} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &539258975 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 539258973} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 08db36445d04347ef86917819b072b76, type: 3} + m_Name: + m_EditorClassIdentifier: + LogText: {fileID: 1321034296} + StatusText: {fileID: 562753628} + HostInput: {fileID: 798780213} + PortInput: {fileID: 115949712} + DataInput: {fileID: 1041758960} + LogScroll: {fileID: 185570085} + ConnectButton: {fileID: 1481597995} + Buttons: + - {fileID: 1309338645} + - {fileID: 1602564545} + - {fileID: 1950926904} + - {fileID: 876135629} + - {fileID: 1287462913} + - {fileID: 1052900978} + - {fileID: 1485904924} + - {fileID: 150526396} +--- !u!1 &562753626 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 562753627} + - component: {fileID: 562753629} + - component: {fileID: 562753628} + m_Layer: 5 + m_Name: StatusText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &562753627 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562753626} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &562753628 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562753626} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Disconnected + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &562753629 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562753626} + m_CullTransparentMesh: 1 +--- !u!1 &569754089 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 569754090} + - component: {fileID: 569754093} + - component: {fileID: 569754092} + - component: {fileID: 569754091} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &569754090 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569754089} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 454989674} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &569754091 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569754089} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &569754092 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569754089} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "Enter some data to test transfer \nor stay empty" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 2150773298 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &569754093 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569754089} + m_CullTransparentMesh: 1 +--- !u!1 &579574895 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 579574896} + - component: {fileID: 579574897} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &579574896 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 579574895} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1309338644} + - {fileID: 1602564544} + - {fileID: 1950926903} + - {fileID: 876135628} + - {fileID: 1287462912} + - {fileID: 1485904923} + - {fileID: 150526395} + - {fileID: 1041758959} + m_Father: {fileID: 1819325582} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.000031207783} + m_SizeDelta: {x: 0, y: 3000} + m_Pivot: {x: 0, y: 1} +--- !u!114 &579574897 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 579574895} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 16 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 16 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &598734667 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 598734668} + - component: {fileID: 598734671} + - component: {fileID: 598734670} + - component: {fileID: 598734669} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &598734668 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598734667} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1341619234} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &598734669 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598734667} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &598734670 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598734667} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Enter text... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &598734671 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598734667} + m_CullTransparentMesh: 1 +--- !u!1 &770291285 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 770291286} + - component: {fileID: 770291288} + - component: {fileID: 770291287} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &770291286 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770291285} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1602564544} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &770291287 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770291285} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Command + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &770291288 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770291285} + m_CullTransparentMesh: 1 +--- !u!1 &775008409 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 775008410} + - component: {fileID: 775008412} + - component: {fileID: 775008411} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &775008410 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 775008409} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1481597994} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &775008411 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 775008409} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Connect + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &775008412 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 775008409} + m_CullTransparentMesh: 1 +--- !u!1 &798780211 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 798780212} + - component: {fileID: 798780215} + - component: {fileID: 798780214} + - component: {fileID: 798780213} + m_Layer: 5 + m_Name: HostInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &798780212 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798780211} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1341619234} + m_Father: {fileID: 207479225} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 320, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &798780213 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798780211} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 798780214} + m_TextViewport: {fileID: 1341619234} + m_TextComponent: {fileID: 2074396582} + m_Placeholder: {fileID: 598734670} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 0 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: 192.168.0.51 + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &798780214 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798780211} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &798780215 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798780211} + m_CullTransparentMesh: 1 +--- !u!1 &860852142 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 860852143} + - component: {fileID: 860852146} + - component: {fileID: 860852145} + - component: {fileID: 860852144} + m_Layer: 5 + m_Name: Scroll View + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &860852143 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 860852142} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1819325582} + - {fileID: 1042330545} + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 1024} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &860852144 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 860852142} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 579574896} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 1819325582} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 1042330546} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &860852145 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 860852142} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &860852146 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 860852142} + m_CullTransparentMesh: 1 +--- !u!1 &876135627 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 876135628} + - component: {fileID: 876135631} + - component: {fileID: 876135630} + - component: {fileID: 876135629} + m_Layer: 5 + m_Name: SubscribeButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &876135628 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 876135627} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 87791715} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &876135629 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 876135627} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 876135630} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Subscribe + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &876135630 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 876135627} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &876135631 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 876135627} + m_CullTransparentMesh: 1 +--- !u!1 &999822692 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 999822693} + - component: {fileID: 999822695} + - component: {fileID: 999822694} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &999822693 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 999822692} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &999822694 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 999822692} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &999822695 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 999822692} + m_CullTransparentMesh: 1 +--- !u!1 &1041758958 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1041758959} + - component: {fileID: 1041758962} + - component: {fileID: 1041758961} + - component: {fileID: 1041758960} + m_Layer: 5 + m_Name: DataInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1041758959 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1041758958} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 454989674} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 144} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1041758960 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1041758958} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1041758961} + m_TextViewport: {fileID: 454989674} + m_TextComponent: {fileID: 504131353} + m_Placeholder: {fileID: 569754092} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 2 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 0 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1041758961 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1041758958} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1041758962 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1041758958} + m_CullTransparentMesh: 1 +--- !u!1 &1042330544 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1042330545} + - component: {fileID: 1042330548} + - component: {fileID: 1042330547} + - component: {fileID: 1042330546} + m_Layer: 5 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1042330545 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042330544} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1251226125} + m_Father: {fileID: 860852143} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 48, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &1042330546 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042330544} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2137896824} + m_HandleRect: {fileID: 2137896823} + m_Direction: 2 + m_Value: 1 + m_Size: 0.34133333 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1042330547 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042330544} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1042330548 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042330544} + m_CullTransparentMesh: 1 +--- !u!1 &1045124896 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1045124897} + - component: {fileID: 1045124899} + - component: {fileID: 1045124898} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1045124897 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1045124896} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1287462912} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1045124898 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1045124896} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Unsubscribe + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1045124899 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1045124896} + m_CullTransparentMesh: 1 +--- !u!1 &1052900976 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1052900977} + - component: {fileID: 1052900980} + - component: {fileID: 1052900979} + - component: {fileID: 1052900978} + m_Layer: 5 + m_Name: DisconnectButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1052900977 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052900976} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1166121420} + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1052900978 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052900976} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1052900979} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Disconnect + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1052900979 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052900976} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1052900980 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052900976} + m_CullTransparentMesh: 1 +--- !u!1 &1074074093 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1074074094} + - component: {fileID: 1074074096} + - component: {fileID: 1074074095} + m_Layer: 5 + m_Name: 'Panel ' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1074074094 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074074093} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1074074095 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074074093} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1074074096 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074074093} + m_CullTransparentMesh: 1 +--- !u!1 &1166121419 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1166121420} + - component: {fileID: 1166121422} + - component: {fileID: 1166121421} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1166121420 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1166121419} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1052900977} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1166121421 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1166121419} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Disconnect + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1166121422 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1166121419} + m_CullTransparentMesh: 1 +--- !u!1 &1189404153 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1189404154} + - component: {fileID: 1189404156} + - component: {fileID: 1189404155} + m_Layer: 5 + m_Name: PortText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1189404154 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1189404153} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 207479225} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 128, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1189404155 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1189404153} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 'Port:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1189404156 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1189404153} + m_CullTransparentMesh: 1 +--- !u!1 &1251226124 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1251226125} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1251226125 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1251226124} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2137896823} + m_Father: {fileID: 1042330545} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1287462911 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1287462912} + - component: {fileID: 1287462915} + - component: {fileID: 1287462914} + - component: {fileID: 1287462913} + m_Layer: 5 + m_Name: UnsubscribeButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1287462912 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287462911} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1045124897} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1287462913 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287462911} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1287462914} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Unsubscribe + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1287462914 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287462911} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1287462915 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287462911} + m_CullTransparentMesh: 1 +--- !u!1 &1309338643 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1309338644} + - component: {fileID: 1309338647} + - component: {fileID: 1309338646} + - component: {fileID: 1309338645} + m_Layer: 5 + m_Name: RequestButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1309338644 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309338643} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2083619548} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1309338645 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309338643} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1309338646} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Request + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1309338646 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309338643} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1309338647 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309338643} + m_CullTransparentMesh: 1 +--- !u!1 &1321034294 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1321034295} + - component: {fileID: 1321034297} + - component: {fileID: 1321034296} + m_Layer: 5 + m_Name: LogText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1321034295 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1321034294} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1561090812} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1321034296 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1321034294} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1321034297 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1321034294} + m_CullTransparentMesh: 1 +--- !u!1 &1341619233 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1341619234} + - component: {fileID: 1341619235} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1341619234 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1341619233} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 598734668} + - {fileID: 2074396581} + m_Father: {fileID: 798780212} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1341619235 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1341619233} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &1353611067 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1353611068} + - component: {fileID: 1353611070} + - component: {fileID: 1353611069} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1353611068 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1353611067} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1950926903} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1353611069 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1353611067} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Error + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1353611070 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1353611067} + m_CullTransparentMesh: 1 +--- !u!1 &1436611974 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1436611975} + - component: {fileID: 1436611977} + - component: {fileID: 1436611976} + m_Layer: 5 + m_Name: TitleText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1436611975 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1436611974} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &1436611976 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1436611974} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 64 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 6 + m_MaxSize: 64 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Shardy demo +--- !u!222 &1436611977 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1436611974} + m_CullTransparentMesh: 1 +--- !u!1 &1461011999 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1461012000} + - component: {fileID: 1461012003} + - component: {fileID: 1461012002} + - component: {fileID: 1461012001} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1461012000 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461011999} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1561090812} + m_Father: {fileID: 185570084} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1461012001 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461011999} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &1461012002 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461011999} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1461012003 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461011999} + m_CullTransparentMesh: 1 +--- !u!1 &1481597993 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1481597994} + - component: {fileID: 1481597997} + - component: {fileID: 1481597996} + - component: {fileID: 1481597995} + m_Layer: 5 + m_Name: ConnectButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1481597994 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481597993} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 775008410} + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1481597995 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481597993} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1481597996} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Connect + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1481597996 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481597993} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1481597997 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481597993} + m_CullTransparentMesh: 1 +--- !u!1 &1485904922 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1485904923} + - component: {fileID: 1485904926} + - component: {fileID: 1485904925} + - component: {fileID: 1485904924} + m_Layer: 5 + m_Name: OnRequestButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1485904923 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485904922} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1662488316} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1485904924 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485904922} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1485904925} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: SubscribeRequest + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1485904925 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485904922} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1485904926 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485904922} + m_CullTransparentMesh: 1 +--- !u!1 &1497364877 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1497364878} + - component: {fileID: 1497364880} + - component: {fileID: 1497364879} + - component: {fileID: 1497364881} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1497364878 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1497364877} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1436611975} + - {fileID: 207479225} + - {fileID: 1481597994} + - {fileID: 1052900977} + - {fileID: 999822693} + - {fileID: 860852143} + - {fileID: 1074074094} + - {fileID: 562753627} + m_Father: {fileID: 1917894912} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 132.00002} + m_SizeDelta: {x: -64, y: -328.00003} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1497364879 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1497364877} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1497364880 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1497364877} + m_CullTransparentMesh: 1 +--- !u!114 &1497364881 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1497364877} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 32 + m_Right: 32 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 16 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &1561090811 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1561090812} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1561090812 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1561090811} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1321034295} + m_Father: {fileID: 1461012000} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 1332.2343} + m_SizeDelta: {x: 0, y: 3000} + m_Pivot: {x: 0, y: 1} +--- !u!1 &1602564543 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1602564544} + - component: {fileID: 1602564547} + - component: {fileID: 1602564546} + - component: {fileID: 1602564545} + m_Layer: 5 + m_Name: CommandButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1602564544 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1602564543} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 770291286} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1602564545 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1602564543} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1602564546} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Command + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1602564546 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1602564543} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1602564547 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1602564543} + m_CullTransparentMesh: 1 +--- !u!1 &1662488315 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1662488316} + - component: {fileID: 1662488318} + - component: {fileID: 1662488317} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1662488316 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662488315} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1485904923} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1662488317 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662488315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: On request + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1662488318 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662488315} + m_CullTransparentMesh: 1 +--- !u!1 &1809996611 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1809996612} + - component: {fileID: 1809996614} + - component: {fileID: 1809996613} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1809996612 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1809996611} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 444005365} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1809996613 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1809996611} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1809996614 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1809996611} + m_CullTransparentMesh: 1 +--- !u!1 &1819325581 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1819325582} + - component: {fileID: 1819325585} + - component: {fileID: 1819325584} + - component: {fileID: 1819325583} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1819325582 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819325581} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 579574896} + m_Father: {fileID: 860852143} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1819325583 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819325581} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &1819325584 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819325581} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1819325585 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819325581} + m_CullTransparentMesh: 1 +--- !u!1 &1917894908 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1917894912} + - component: {fileID: 1917894911} + - component: {fileID: 1917894910} + - component: {fileID: 1917894909} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1917894909 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1917894908} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1917894910 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1917894908} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 0.5 + m_ReferenceResolution: {x: 1080, y: 1920} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0.5 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1917894911 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1917894908} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1917894912 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1917894908} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1497364878} + - {fileID: 185570084} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &1926762627 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1926762628} + - component: {fileID: 1926762630} + - component: {fileID: 1926762629} + m_Layer: 5 + m_Name: HostText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1926762628 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1926762627} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 207479225} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 128, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1926762629 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1926762627} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 'Host:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1926762630 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1926762627} + m_CullTransparentMesh: 1 +--- !u!1 &1950926902 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1950926903} + - component: {fileID: 1950926906} + - component: {fileID: 1950926905} + - component: {fileID: 1950926904} + m_Layer: 5 + m_Name: ErrorButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1950926903 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1950926902} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1353611068} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1950926904 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1950926902} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1950926905} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Error + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1950926905 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1950926902} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1950926906 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1950926902} + m_CullTransparentMesh: 1 +--- !u!1 &2074396580 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2074396581} + - component: {fileID: 2074396583} + - component: {fileID: 2074396582} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2074396581 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2074396580} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1341619234} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2074396582 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2074396580} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "192.168.0.51\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2074396583 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2074396580} + m_CullTransparentMesh: 1 +--- !u!1 &2083619547 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2083619548} + - component: {fileID: 2083619550} + - component: {fileID: 2083619549} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2083619548 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2083619547} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1309338644} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2083619549 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2083619547} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Request + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2083619550 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2083619547} + m_CullTransparentMesh: 1 +--- !u!1 &2097740589 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2097740592} + - component: {fileID: 2097740591} + - component: {fileID: 2097740590} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2097740590 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2097740589} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "3000\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2097740591 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2097740589} + m_CullTransparentMesh: 1 +--- !u!224 &2097740592 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2097740589} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 322493275} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &2098744276 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2098744280} + - component: {fileID: 2098744279} + - component: {fileID: 2098744277} + - component: {fileID: 2098744278} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2098744277 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2098744276} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Enter text... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &2098744278 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2098744276} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!222 &2098744279 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2098744276} + m_CullTransparentMesh: 1 +--- !u!224 &2098744280 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2098744276} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 322493275} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &2137896822 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2137896823} + - component: {fileID: 2137896825} + - component: {fileID: 2137896824} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2137896823 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2137896822} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1251226125} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2137896824 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2137896822} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2137896825 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2137896822} + m_CullTransparentMesh: 1 +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 519420032} + - {fileID: 1917894912} + - {fileID: 86744318} + - {fileID: 539258974} diff --git a/Samples~/Demo/Scenes/Demo.unity.meta b/Samples~/Demo/Scenes/Demo.unity.meta new file mode 100644 index 0000000..9d4e2bb --- /dev/null +++ b/Samples~/Demo/Scenes/Demo.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 04958b545c3e04b579450370a955cefe +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts.meta b/Samples~/Demo/Scripts.meta new file mode 100644 index 0000000..f8aa446 --- /dev/null +++ b/Samples~/Demo/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 44d6ca945a6bd42b8843c8dc70d17554 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts/Demo.cs b/Samples~/Demo/Scripts/Demo.cs new file mode 100644 index 0000000..8ce6283 --- /dev/null +++ b/Samples~/Demo/Scripts/Demo.cs @@ -0,0 +1,263 @@ +using UnityEngine; +using Shardy; +using System.Text; +using TMPro; +using UnityEngine.UI; + +public class Demo : MonoBehaviour { + + /// + /// Link to log text + /// + [SerializeField] + TextMeshProUGUI LogText = null; + + /// + /// Link to status text + /// + [SerializeField] + TextMeshProUGUI StatusText = null; + + /// + /// Input field for host + /// + [SerializeField] + TMP_InputField HostInput = null; + + /// + /// Input field for port + /// + [SerializeField] + TMP_InputField PortInput = null; + + /// + /// Input field for data + /// + [SerializeField] + TMP_InputField DataInput = null; + + /// + /// Scroll for logs + /// + [SerializeField] + ScrollRect LogScroll = null; + + /// + /// Link to connect button + /// + [SerializeField] + Button ConnectButton = null; + + /// + /// Array with buttons + /// + [SerializeField] + Button[] Buttons = null; + + /// + /// Client instance + /// + Client _client = null; + + /// + /// Cached data + /// + byte[] _data = null; + + /// + /// Init + /// + /// This demo uses TCP transport for connecting to test service + /// If you want to test client on your own backend with Websockets, change it in ClientOptions + /// + void Awake() { + LogScroll.verticalNormalizedPosition = 1f; + SwitchControls(false); + _client = new Client(new MyHandshake(), new MyJSON(), new ClientOptions()); + _client.OnConnect += OnConnect; + _client.OnDisconnect += OnDisconnect; + _client.OnReady += OnReady; + } + + /// + /// Destroy client + /// + void OnDestroy() { + _client.Destroy(); + } + + /// + /// Callback on ready to work + /// + void OnReady() { + StatusText.text = "Ready"; + LogText.text += $"< ready\n"; + } + + /// + /// Callback on disconnect with reason + /// + void OnDisconnect(DisconnectReason reason) { + LogText.text += $"< disconnected\n"; + StatusText.text = $"Disconnected: {reason}"; + Scroll(); + SwitchControls(false); + } + + /// + /// Callback on connect with status + /// + void OnConnect(bool status) { + LogText.text += status ? $"< connected\n" : $"< failed\n"; + StatusText.text = status ? "Connected" : "Disconnected"; + SwitchControls(status); + if (status) { + _client.Handshake(); + } + } + + /// + /// On/off controls + /// + void SwitchControls(bool value) { + ConnectButton.interactable = !value; + foreach (var item in Buttons) { + item.interactable = value; + } + DataInput.interactable = value; + } + + /// + /// Connect to server + /// + public void Connect() { + var host = HostInput.text.Trim(); + var port = int.Parse(PortInput.text.Trim()); + LogText.text += $"> connect to: {host}:{port}\n"; + _client.Connect(host, port); + } + + /// + /// Disconnect + /// + public void Disconnect() { + LogText.text += $"> disconnect\n"; + _client.Disconnect(); + Scroll(); + } + + /// + /// Test request + /// + public void Request() { + PrepareData(); + var request = "status"; + LogText.text += $"> test request: {request}\n"; + _client.Request(request, _data, (response) => { + LogText.text += $"< request data: {Utils.DataToString(response.Data)}\n\n"; + Scroll(); + }); + Scroll(); + } + + /// + /// Test command + /// + public void Command() { + PrepareData(); + var command = "notify"; + LogText.text += $"> test command: {command}\n"; + _client.Command(command, _data); + Scroll(); + } + + /// + /// Test request with error response + /// + public void Error() { + PrepareData(); + var request = "fail"; + LogText.text += $"> test error: {request}\n"; + _client.Request(request, _data, (response) => { + LogText.text += $"< error data: {Utils.DataToString(response.Data)}\n\n"; + Scroll(); + }); + Scroll(); + } + + /// + /// Subscribe on command + /// + public void Subscribe() { + PrepareData(); + var command = "timer"; + LogText.text += $"> subscribe on command: {command}\n"; + _client.Command(command, Encoding.UTF8.GetBytes("yes")); + _client.On(command, OnCommand); + Scroll(); + } + + /// + /// Unsubscribe from command + /// + public void Unsubscribe() { + PrepareData(); + var command = "timer"; + LogText.text += $"> unsubscribe from command: {command}\n"; + _client.Command(command, Encoding.UTF8.GetBytes("no")); + _client.Off(command, OnCommand); + Scroll(); + } + + /// + /// Add callback for request from server + /// Need respond or will be timeout + /// + /// Send command to initiate this example + /// + public void SubscribeRequest() { + var request = "request"; + LogText.text += $"> subscribe on request: {request}\n"; + _client.OnRequest(request, (payload) => { + // make response on this request id + // + // if comment this, you will give timeout on your backend + _client.Response(payload, Encoding.UTF8.GetBytes("some_data_from_client")); + }); + _client.Command(request); + } + + /// + /// Unsubscribe from server request + /// + /// Send command to initiate example and check that callback above doesn't invoke + /// + public void UnsubscribeRequest() { + var request = "request"; + LogText.text += $"> unsubscribe from request: {request}\n"; + _client.OffRequest(request); + _client.Command(request); + } + + /// + /// Callback on subscribed command + /// + void OnCommand(PayloadData payload) { + LogText.text += $"< subscribe data: {Utils.DataToString(payload.Data)}\n\n"; + Scroll(); + } + + /// + /// Prepare data to transport + /// + void PrepareData() { + _data = !string.IsNullOrEmpty(DataInput.text) ? Encoding.UTF8.GetBytes(DataInput.text) : null; + } + + /// + /// Scroll to bottom with some step + /// + void Scroll() { + LogScroll.verticalNormalizedPosition -= 0.035f; + } +} diff --git a/Samples~/Demo/Scripts/Demo.cs.meta b/Samples~/Demo/Scripts/Demo.cs.meta new file mode 100644 index 0000000..3675751 --- /dev/null +++ b/Samples~/Demo/Scripts/Demo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08db36445d04347ef86917819b072b76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts/MyHandshake.cs b/Samples~/Demo/Scripts/MyHandshake.cs new file mode 100644 index 0000000..e1ec016 --- /dev/null +++ b/Samples~/Demo/Scripts/MyHandshake.cs @@ -0,0 +1,38 @@ +using System.Text; +using Shardy; + +/// +/// Handshake stub +/// +class MyHandshake : IValidator { + + /// + /// Data for acknowledgement + /// + public byte[] Acknowledgement(byte[] body) { + // + // generate as you wish here + // + return body; + } + + /// + /// Data for initial handshake + /// + public byte[] Handshake(byte[] body = null) { + // + // generate as you wish here + // + return Encoding.UTF8.GetBytes("handshake_data"); + } + + /// + /// Verify acknowledgement + /// + public ValidatorState VerifyAcknowledgement(byte[] body) { + // + // validate as you wish here + // + return ValidatorState.Success; + } +} \ No newline at end of file diff --git a/Samples~/Demo/Scripts/MyHandshake.cs.meta b/Samples~/Demo/Scripts/MyHandshake.cs.meta new file mode 100644 index 0000000..53a7b9d --- /dev/null +++ b/Samples~/Demo/Scripts/MyHandshake.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 153935054a6164c40924eb2d7a2d611f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts/MyJSON.cs b/Samples~/Demo/Scripts/MyJSON.cs new file mode 100644 index 0000000..2cb85b0 --- /dev/null +++ b/Samples~/Demo/Scripts/MyJSON.cs @@ -0,0 +1,30 @@ +using System.Text; +using NiceJson; +using Shardy; + +/// +/// Simple example serializer via NiceJson +/// +class MyJSON : ISerializer { + + /// + /// Decode received data to PayloadData + /// + public PayloadData Decode(byte[] body) { + var data = (JsonObject)JsonNode.ParseJsonString(Encoding.UTF8.GetString(body)); + return new PayloadData((PayloadType)(int)data["type"], data["name"], data["id"], Encoding.UTF8.GetBytes(data["data"]), data["error"]); + } + + /// + /// Encode to byte array for transporting + /// + public byte[] Encode(PayloadData payload) { + var data = new JsonObject(); + data["type"] = (int)payload.Type; + data["name"] = payload.Name; + data["id"] = payload.Id; + data["data"] = (payload.Data != null) ? Encoding.UTF8.GetString(payload.Data) : string.Empty; + data["error"] = payload.Error; + return Encoding.UTF8.GetBytes(data.ToJsonString()); + } +} \ No newline at end of file diff --git a/Samples~/Demo/Scripts/MyJSON.cs.meta b/Samples~/Demo/Scripts/MyJSON.cs.meta new file mode 100644 index 0000000..44a65ae --- /dev/null +++ b/Samples~/Demo/Scripts/MyJSON.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d4584e4fdf6f4b98bccc655cb42aa00 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts/NiceJson.cs b/Samples~/Demo/Scripts/NiceJson.cs new file mode 100644 index 0000000..f797331 --- /dev/null +++ b/Samples~/Demo/Scripts/NiceJson.cs @@ -0,0 +1,769 @@ +/* + NiceJson 1.3.3 (2020-05-11) + + MIT License + =========== + + Copyright (C) 2015 Ángel Quiroga Mendoza + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Appreciation Contributions: + Rayco Sánchez García +*/ + +using System; +using System.Collections.Generic; +using System.Collections; +using System.Globalization; +using System.Text; + +namespace NiceJson { + [Serializable] + public abstract class JsonNode { + protected const char PP_IDENT_CHAR = '\t'; //Modify this to spaces or whatever char you want to be the ident one + protected const int PP_IDENT_COUNT = 1; //Modify this to be the numbers of IDENT_CHAR x identation + protected const bool ESCAPE_SOLIDUS = false; //If you are going to to embed this json in html, you can turn this on ref: http://andowebsit.es/blog/noteslog.com/post/the-solidus-issue/ + + protected const char CHAR_CURLY_OPEN = '{'; + protected const char CHAR_CURLY_CLOSED = '}'; + protected const char CHAR_SQUARED_OPEN = '['; + protected const char CHAR_SQUARED_CLOSED = ']'; + + protected const char CHAR_COLON = ':'; + protected const char CHAR_COMMA = ','; + protected const char CHAR_QUOTE = '"'; + + protected const char CHAR_NULL_LITERAL = 'n'; + protected const char CHAR_TRUE_LITERAL = 't'; + protected const char CHAR_FALSE_LITERAL = 'f'; + + protected const char CHAR_SPACE = ' '; + + protected const char CHAR_BS = '\b'; + protected const char CHAR_FF = '\f'; + protected const char CHAR_RF = '\r'; + protected const char CHAR_NL = '\n'; + protected const char CHAR_HT = '\t'; + protected const char CHAR_ESCAPE = '\\'; + protected const char CHAR_SOLIDUS = '/'; + protected const char CHAR_ESCAPED_QUOTE = '\"'; + + protected const char CHAR_N = 'n'; + protected const char CHAR_R = 'r'; + protected const char CHAR_B = 'b'; + protected const char CHAR_T = 't'; + protected const char CHAR_F = 'f'; + protected const char CHAR_U = 'u'; + + protected const string STRING_ESCAPED_BS = "\\b"; + protected const string STRING_ESCAPED_FF = "\\f"; + protected const string STRING_ESCAPED_RF = "\\r"; + protected const string STRING_ESCAPED_NL = "\\n"; + protected const string STRING_ESCAPED_TAB = "\\t"; + protected const string STRING_ESCAPED_ESCAPE = "\\\\"; + protected const string STRING_ESCAPED_SOLIDUS = "\\/"; + protected const string STRING_ESCAPED_ESCAPED_QUOTE = "\\\""; + + protected const string STRING_SPACE = " "; + protected const string STRING_LITERAL_NULL = "null"; + protected const string STRING_LITERAL_TRUE = "true"; + protected const string STRING_LITERAL_FALSE = "false"; + + protected const string STRING_ESCAPED_UNICODE_INIT = "\\u00"; + + //Indexers and accesors + public JsonNode this[string key] { + get { + if (this is JsonObject) { + return ((JsonObject)this)[key]; + } else { + return null; + } + } + + set { + if (this is JsonObject) { + ((JsonObject)this)[key] = value; + } + } + } + + public JsonNode this[int index] { + get { + if (this is JsonArray) { + return ((JsonArray)this)[index]; + } else { + return null; + } + } + + set { + if (this is JsonArray) { + ((JsonArray)this)[index] = value; + } + } + } + + public bool ContainsKey(string key) { + if (this is JsonObject) { + return ((JsonObject)this).ContainsKey(key); + } else { + return false; + } + } + + //escaping logic + + //Escaping/Unescaping logic + protected static string EscapeString(string s) { + var result = new StringBuilder(); + + foreach (var c in s) { + switch (c) { + case CHAR_ESCAPE: { + result.Append(STRING_ESCAPED_ESCAPE); + } + break; + case CHAR_SOLIDUS: { +#pragma warning disable + if (ESCAPE_SOLIDUS) { + result.Append(STRING_ESCAPED_SOLIDUS); + } else { + result.Append(c); + } +#pragma warning restore + } + break; + case CHAR_ESCAPED_QUOTE: { + _ = result.Append(STRING_ESCAPED_ESCAPED_QUOTE); + } + break; + case CHAR_NL: { + _ = result.Append(STRING_ESCAPED_NL); + } + break; + case CHAR_RF: { + _ = result.Append(STRING_ESCAPED_RF); + } + break; + case CHAR_HT: { + _ = result.Append(STRING_ESCAPED_TAB); + } + break; + case CHAR_BS: { + _ = result.Append(STRING_ESCAPED_BS); + } + break; + case CHAR_FF: { + _ = result.Append(STRING_ESCAPED_FF); + } + break; + default: + if (c < CHAR_SPACE) { + _ = result.Append(STRING_ESCAPED_UNICODE_INIT + Convert.ToByte(c).ToString("x2").ToUpper()); + } else { + _ = result.Append(c); + } + break; + } + } + + return result.ToString(); + } + + protected static string UnescapeString(string s) { + var result = new StringBuilder(s.Length); + + for (var i = 0; i < s.Length; i++) { + if (s[i] == CHAR_ESCAPE) { + i++; + + switch (s[i]) { + case CHAR_ESCAPE: { + _ = result.Append(s[i]); + } + break; + case CHAR_SOLIDUS: { + _ = result.Append(s[i]); + } + break; + case CHAR_ESCAPED_QUOTE: { + _ = result.Append(s[i]); + } + break; + case CHAR_N: { + _ = result.Append(CHAR_NL); + } + break; + case CHAR_R: { + _ = result.Append(CHAR_RF); + } + break; + case CHAR_T: { + _ = result.Append(CHAR_HT); + } + break; + case CHAR_B: { + _ = result.Append(CHAR_BS); + } + break; + case CHAR_F: { + _ = result.Append(CHAR_FF); + } + break; + case CHAR_U: { + _ = result.Append((char)int.Parse(s.Substring(i + 1, 4), NumberStyles.AllowHexSpecifier)); + i = i + 4; + } + break; + default: { + _ = result.Append(s[i]); + } + break; + } + } else { + _ = result.Append(s[i]); + } + } + + return result.ToString(); + } + + //setter implicit casting + + public static implicit operator JsonNode(string value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(int value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(long value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(float value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(double value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(decimal value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(bool value) { + return new JsonBasic(value); + } + + //getter implicit casting + + public static implicit operator string(JsonNode value) { + if (value != null) { + return value.ToString(); + } else { + return null; + } + } + + public static implicit operator int(JsonNode value) { + return (int)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(int)); + } + + public static implicit operator long(JsonNode value) { + return (long)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(long)); + } + + public static implicit operator float(JsonNode value) { + return (float)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(float)); + } + + public static implicit operator double(JsonNode value) { + return (double)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(double)); + } + + public static implicit operator decimal(JsonNode value) { + return (decimal)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(decimal)); + } + + public static implicit operator bool(JsonNode value) { + return (bool)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(bool)); + } + + //Parsing logic + public static JsonNode ParseJsonString(string jsonString) { + return ParseJsonPart(RemoveNonTokenChars(jsonString)); + } + + private static JsonNode ParseJsonPart(string jsonPart) { + JsonNode jsonPartValue = null; + + if (jsonPart.Length == 0) { + return jsonPartValue; + } + + switch (jsonPart[0]) { + case CHAR_CURLY_OPEN: { + var jsonObject = new JsonObject(); + var splittedParts = SplitJsonParts(jsonPart.Substring(1, jsonPart.Length - 2)); + _ = new string[2]; + foreach (var keyValuePart in splittedParts) { + var keyValueParts = SplitKeyValuePart(keyValuePart); + if (keyValueParts[0] != null) { + jsonObject[UnescapeString(keyValueParts[0])] = ParseJsonPart(keyValueParts[1]); + } + } + jsonPartValue = jsonObject; + } + break; + case CHAR_SQUARED_OPEN: { + var jsonArray = new JsonArray(); + var splittedParts = SplitJsonParts(jsonPart.Substring(1, jsonPart.Length - 2)); + + foreach (var part in splittedParts) { + if (part.Length > 0) { + jsonArray.Add(ParseJsonPart(part)); + } + } + jsonPartValue = jsonArray; + } + break; + case CHAR_QUOTE: { + jsonPartValue = new JsonBasic(UnescapeString(jsonPart.Substring(1, jsonPart.Length - 2))); + } + break; + case CHAR_FALSE_LITERAL://false + { + jsonPartValue = new JsonBasic(false); + } + break; + case CHAR_TRUE_LITERAL://true + { + jsonPartValue = new JsonBasic(true); + } + break; + case CHAR_NULL_LITERAL://null + { + jsonPartValue = null; + } + break; + default://it must be a number or it will fail + { + long longValue; + if (long.TryParse(jsonPart, NumberStyles.Any, CultureInfo.InvariantCulture, out longValue)) { + if (longValue > int.MaxValue || longValue < int.MinValue) { + jsonPartValue = new JsonBasic(longValue); + } else { + jsonPartValue = new JsonBasic((int)longValue); + } + } else { + decimal decimalValue; + if (decimal.TryParse(jsonPart, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalValue)) { + jsonPartValue = new JsonBasic(decimalValue); + } + } + } + break; + } + + return jsonPartValue; + } + + private static List SplitJsonParts(string json) { + var jsonParts = new List(); + var identLevel = 0; + var lastPartChar = 0; + var inString = false; + + for (var i = 0; i < json.Length; i++) { + switch (json[i]) { + case CHAR_COMMA: { + if (!inString && identLevel == 0) { + jsonParts.Add(json.Substring(lastPartChar, i - lastPartChar)); + lastPartChar = i + 1; + } + } + break; + case CHAR_QUOTE: { + if (i == 0 || (json[i - 1] != CHAR_ESCAPE)) { + inString = !inString; + } + } + break; + case CHAR_CURLY_OPEN: + case CHAR_SQUARED_OPEN: { + if (!inString) { + identLevel++; + } + } + break; + case CHAR_CURLY_CLOSED: + case CHAR_SQUARED_CLOSED: { + if (!inString) { + identLevel--; + } + } + break; + } + } + + jsonParts.Add(json.Substring(lastPartChar)); + + return jsonParts; + } + + private static string[] SplitKeyValuePart(string json) { + var parts = new string[2]; + var inString = false; + + var found = false; + var index = 0; + + while (index < json.Length && !found) { + if (json[index] == CHAR_QUOTE && (index == 0 || (json[index - 1] != CHAR_ESCAPE))) { + if (!inString) { + inString = true; + index++; + } else { + parts[0] = json.Substring(1, index - 1); + parts[1] = json.Substring(index + 2);//+2 because of the : + found = true; + } + } else { + index++; + } + } + + return parts; + } + + private static string RemoveNonTokenChars(string s) { + var len = s.Length; + var s2 = new char[len]; + var currentPos = 0; + var outString = true; + for (var i = 0; i < len; i++) { + var c = s[i]; + if (c == CHAR_QUOTE) { + if (i == 0 || (s[i - 1] != CHAR_ESCAPE)) { + outString = !outString; + } + } + + if (!outString || ( + (c != CHAR_SPACE) && + (c != CHAR_RF) && + (c != CHAR_NL) && + (c != CHAR_HT) && + (c != CHAR_BS) && + (c != CHAR_FF) + )) { + s2[currentPos++] = c; + } + } + return new String(s2, 0, currentPos); + } + + //Object logic + + public abstract string ToJsonString(); + + public string ToJsonPrettyPrintString() { + var jsonString = this.ToJsonString(); + + var identStep = string.Empty; + for (var i = 0; i < PP_IDENT_COUNT; i++) { + identStep += PP_IDENT_CHAR; + } + + var inString = false; + + var currentIdent = string.Empty; + for (var i = 0; i < jsonString.Length; i++) { + switch (jsonString[i]) { + case CHAR_COLON: { + if (!inString) { + jsonString = jsonString.Insert(i + 1, STRING_SPACE); + } + } + break; + case CHAR_QUOTE: { + if (i == 0 || (jsonString[i - 1] != CHAR_ESCAPE)) { + inString = !inString; + } + } + break; + case CHAR_COMMA: { + if (!inString) { + jsonString = jsonString.Insert(i + 1, CHAR_NL + currentIdent); + } + } + break; + case CHAR_CURLY_OPEN: + case CHAR_SQUARED_OPEN: { + if (!inString) { + currentIdent += identStep; + jsonString = jsonString.Insert(i + 1, CHAR_NL + currentIdent); + } + } + break; + case CHAR_CURLY_CLOSED: + case CHAR_SQUARED_CLOSED: { + if (!inString) { + currentIdent = currentIdent.Substring(0, currentIdent.Length - identStep.Length); + jsonString = jsonString.Insert(i, CHAR_NL + currentIdent); + i += currentIdent.Length + 1; + } + } + break; + } + } + + return jsonString; + } + } + + [Serializable] + public class JsonBasic : JsonNode { + public object ValueObject { + get { + return m_value; + } + } + + private object m_value; + + public JsonBasic(object value) { + m_value = value; + } + + public override string ToString() { + return m_value.ToString(); + } + + public override string ToJsonString() { + if (m_value == null) { + return STRING_LITERAL_NULL; + } else if (m_value is string) { + return CHAR_QUOTE + EscapeString(m_value.ToString()) + CHAR_QUOTE; + } else if (m_value is bool) { + if ((bool)m_value) { + return STRING_LITERAL_TRUE; + } else { + return STRING_LITERAL_FALSE; + } + } else //number + { + if (m_value is decimal) { + return ((decimal)m_value).ToString(CultureInfo.InvariantCulture); + } else { + return m_value.ToString(); + } + } + } + } + + [Serializable] + public class JsonObject : JsonNode, IEnumerable { + private Dictionary m_dictionary = new Dictionary(); + + public Dictionary.KeyCollection Keys { + get { + return m_dictionary.Keys; + } + } + + public Dictionary.ValueCollection Values { + get { + return m_dictionary.Values; + } + } + + public new JsonNode this[string key] { + get { + return m_dictionary[key]; + } + + set { + m_dictionary[key] = value; + } + } + + public void Add(string key, JsonNode value) { + m_dictionary.Add(key, value); + } + + public bool Remove(string key) { + return m_dictionary.Remove(key); + } + + public JsonNode GetValue(string key, JsonNode defaultValue = default(JsonNode)) { + JsonNode value; + return m_dictionary.TryGetValue(key, out value) ? value : defaultValue; + } + + public new bool ContainsKey(string key) { + return m_dictionary.ContainsKey(key); + } + + public bool ContainsValue(JsonNode value) { + return m_dictionary.ContainsValue(value); + } + + public void Clear() { + m_dictionary.Clear(); + } + + public int Count { + get { + return m_dictionary.Count; + } + } + + public IEnumerator GetEnumerator() { + foreach (var jsonKeyValue in m_dictionary) { + yield return jsonKeyValue; + } + } + + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + public override string ToJsonString() { + if (m_dictionary == null) { + return STRING_LITERAL_NULL; + } else { + var jsonString = new StringBuilder(); + _ = jsonString.Append(CHAR_CURLY_OPEN); + foreach (var key in m_dictionary.Keys) { + _ = jsonString.Append(CHAR_QUOTE); + _ = jsonString.Append(EscapeString(key)); + _ = jsonString.Append(CHAR_QUOTE); + _ = jsonString.Append(CHAR_COLON); + + if (m_dictionary[key] != null) { + _ = jsonString.Append(m_dictionary[key].ToJsonString()); + } else { + _ = jsonString.Append(STRING_LITERAL_NULL); + } + _ = jsonString.Append(CHAR_COMMA); + } + if (jsonString[jsonString.Length - 1] == CHAR_COMMA) { + _ = jsonString.Remove(jsonString.Length - 1, 1); + } + _ = jsonString.Append(CHAR_CURLY_CLOSED); + + return jsonString.ToString(); + } + } + } + + [Serializable] + public class JsonArray : JsonNode, IEnumerable { + private List m_list = new List(); + + public int Count { + get { + return m_list.Count; + } + } + + public new JsonNode this[int index] { + get { + return m_list[index]; + } + + set { + m_list[index] = value; + } + } + + public IEnumerator GetEnumerator() { + foreach (var value in m_list) { + yield return value; + } + } + + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + //expose some methods of list extends with needs + + public void Add(JsonNode item) { + m_list.Add(item); + } + + public void AddRange(IEnumerable collection) { + m_list.AddRange(collection); + } + + public void Insert(int index, JsonNode item) { + m_list.Insert(index, item); + } + + public void InsertRange(int index, IEnumerable collection) { + m_list.InsertRange(index, collection); + } + + public void RemoveAt(int index) { + m_list.RemoveAt(index); + } + + public bool Remove(JsonNode item) { + return m_list.Remove(item); + } + + public void Clear() { + m_list.Clear(); + } + + //end exposed methods + + + public override string ToJsonString() { + if (m_list == null) { + return STRING_LITERAL_NULL; + } else { + var jsonString = new StringBuilder(); + _ = jsonString.Append(CHAR_SQUARED_OPEN); + foreach (var value in m_list) { + if (value != null) { + _ = jsonString.Append(value.ToJsonString()); + } else { + _ = jsonString.Append(STRING_LITERAL_NULL); + } + + _ = jsonString.Append(CHAR_COMMA); + } + if (jsonString[jsonString.Length - 1] == CHAR_COMMA) { + _ = jsonString.Remove(jsonString.Length - 1, 1); + } + _ = jsonString.Append(CHAR_SQUARED_CLOSED); + + return jsonString.ToString(); + } + } + } +} \ No newline at end of file diff --git a/Samples~/Demo/Scripts/NiceJson.cs.meta b/Samples~/Demo/Scripts/NiceJson.cs.meta new file mode 100644 index 0000000..973f72f --- /dev/null +++ b/Samples~/Demo/Scripts/NiceJson.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 582b2ee812a0e45af84cc1fdffd10a61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe.meta b/Samples~/TicTacToe.meta new file mode 100644 index 0000000..91e55af --- /dev/null +++ b/Samples~/TicTacToe.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 12f27a11ec10041d583430efb13c736d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Images.meta b/Samples~/TicTacToe/Images.meta new file mode 100644 index 0000000..a95ab5c --- /dev/null +++ b/Samples~/TicTacToe/Images.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a254545fc86ae4b68ba6ac3fb21cf951 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Images/circle-icon.png b/Samples~/TicTacToe/Images/circle-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b30185c0c32153fe88d353bdf52a7dcc08ccfab3 GIT binary patch literal 9648 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 E0Jf>yX#fBK literal 0 HcmV?d00001 diff --git a/Samples~/TicTacToe/Images/circle-icon.png.meta b/Samples~/TicTacToe/Images/circle-icon.png.meta new file mode 100644 index 0000000..72362a0 --- /dev/null +++ b/Samples~/TicTacToe/Images/circle-icon.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: 39f8dc9a87dfb4a2c9020e4d96806394 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Images/cross-icon.png b/Samples~/TicTacToe/Images/cross-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c0c1cc38543dc3b0dbe260589c5514303d490c9a GIT binary patch literal 3083 zcmdUxYg7|g9>8bDqzj=Q4Dzt*)>jn)Env@zx|N{3M6D>eLO@M?9jaD&`Dj3yyLA;% z6uWMrR%B2QSXUrm6sQWx`U2E#tQD6L6}DImkbtX`1ZJF>y>q|xtH*XfY|hF2=Kk;b z-}}2acmA3D<;$W+D#j`>3>z7WOUk6@&D>G%5jB)^7D4YEsMvJ z^v*t_x4~tmr)@-CwAFWq&&`3vzdxD2bJdu}=KQMqtDODJb{9Vap$@|t#`edl{YK{4|@ zcJvd|+dABXUi~v-t>@B+Y zjYAiif!jgF?C{k+p{kre1jidRqVLw?inV)Z->Rw$x&4))e$%^?D3z&FbbRo9)=|QEy%O5}1;A%eGt)a?DTwtAEY1yQFqkYh?t6EUB z^mWFXp735r+l<9vGh!j=Ma%_i77j!<0UEImsHK6)YCt1a03C{#f?>oWphNK^U>NZL zh(z&h{E$5%Y?b(s@U}@p+vGEzNu zfh5FgkcC(QzCkPnml2D=Bg7+sMLYn!C6YRPnQ7<2 z;Qm+zgKNuRtk=;_(i@-8ek5lssx@Jh5P|PyV@KaRuZj)R3%lJc|DvXqX~Zis#%lJs zXAo@!>+p58bcnO@MlMsv43GvO@O}jAG{%@*`1gn?i&zeV+0n9sAH>UG1*_VFpJ9yt z+7iKijcE=a=r-n@c-=cFPBaroLKd&U^rYXoW~H(==^&BEFHs-Pn-dU;-xbPBBCX>+ z<;%I^eJ2zBBJl@8dF74V)7WWYg^G-nIg(Cw1fW2Z;v$&iSE4 zDH?h!M~c#gt@$t-J58CpRZ-^9{IMW!j=w_d2#i)LgXwt8AU=JzcJ(Vk(GYUoA3V|E zjG!oUCSZ+5!oqun4eGHhQhtvM0PrxpQCGE;qZZ@LDTo-H`4VCg&iol78fVfW zqHty%L?q6vfQZ1E1rXsl6AZBsXC^@`z!@b37HGm>%U{HniNs#zvqRd>cZO%T|87#K z%c~XN7GC3n{t|qE=jS{Yawgppa;APS`+g{>Ibs z5Jfzl3GwxB@K7yvSk0a_A^CZEQ@D8f_{fOy)imX=wFRxuSPu*Nu^4LyHAAavs#B>= z%|lOxjkx}&Yw()d{QzFC{HKs_B}$u99lmZuqXOVHG5_QUE>k|<8c{-10bMgDuWu7p z;^&ph^sDR03UIhv9JtiDojeWfwpi!b7*qIwstB0*Xpa{)T;T^@8DhHZV@Bw9X?R3> z;_gOqI#KPM5RRP^#}G|c)fZTlsFXc^U^HTjMS<8p(3y;#B~$Tw`(OZgVAO*S&gp6D z>x?(8;W^hb`=D>vfY2y=!8$#Hs>liW4Pmcr>0oC#W+2^h17r3Hvr&QCI)R3D+#tXE zNR@zn2UksVDGIIA>=_g*ehf>qj_B#9rkVsb(PN{gAP!QKBzpIDt_8e7Hshi362_&t zCSD|yafjKX=5w)#uu@aC#|4|LUA4rN!6&=ckVRk++oAVGZHFESY;o$5K%Y~O@{<@15`b?$m6E`xZRA`@;9j*jOA;vC zB;J%mfv^tYkU|o8$oq_z1Z-U3WNF}8tQiSpux2#z1=frve94;8M6)v}Lj5d5p?H?v2#dWz#`KfLl8}WKcOjvAaT^laEuKI^q7Z_1M9D^f zmb$vJZ7Wyr@q+EUKdxiL<9@oYd`Z=O-NtjPp8s&{(vo<6=(wKs0avIG?LXBXPbzH= z44v6{W!C-1U8PNXGPBYJ;mM7t!=lU8Y%(XE?fLn~lk-%A8aB9f^Vzg5$KdNO78AKF KqI#kBi~j-#7m9=c literal 0 HcmV?d00001 diff --git a/Samples~/TicTacToe/Images/cross-icon.png.meta b/Samples~/TicTacToe/Images/cross-icon.png.meta new file mode 100644 index 0000000..b956ba7 --- /dev/null +++ b/Samples~/TicTacToe/Images/cross-icon.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: 2441ef3d25cc740b5b3783c7c86413eb +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scenes.meta b/Samples~/TicTacToe/Scenes.meta new file mode 100644 index 0000000..b18a4c7 --- /dev/null +++ b/Samples~/TicTacToe/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fdebd3cff83c043aeb5d0e4b0f4e72cd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scenes/Game.unity b/Samples~/TicTacToe/Scenes/Game.unity new file mode 100644 index 0000000..dd08529 --- /dev/null +++ b/Samples~/TicTacToe/Scenes/Game.unity @@ -0,0 +1,2589 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &97341221 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 97341222} + - component: {fileID: 97341223} + m_Layer: 0 + m_Name: Scripts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &97341222 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 97341221} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &97341223 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 97341221} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ad76e2a6f3bc4bb5a80c3869758dc7e, type: 3} + m_Name: + m_EditorClassIdentifier: + PlayField: {fileID: 2120814422} + CrossIcon: {fileID: 21300000, guid: 2441ef3d25cc740b5b3783c7c86413eb, type: 3} + CircleIcon: {fileID: 21300000, guid: 39f8dc9a87dfb4a2c9020e4d96806394, type: 3} + CrossColor: {r: 1, g: 0, b: 0, a: 1} + CircleColor: {r: 0, g: 1, b: 0, a: 1} + ScoreText: {fileID: 1386850861} + StatusText: {fileID: 1197697554} +--- !u!1 &125874181 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 125874182} + - component: {fileID: 125874185} + - component: {fileID: 125874184} + - component: {fileID: 125874183} + m_Layer: 5 + m_Name: ExitButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &125874182 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 125874181} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1759215197} + m_Father: {fileID: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 0.5, y: 0} + m_AnchoredPosition: {x: 0, y: 32} + m_SizeDelta: {x: 320, y: 96} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &125874183 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 125874181} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 125874184} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 97341223} + m_TargetAssemblyTypeName: GameController, Assembly-CSharp + m_MethodName: Exit + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &125874184 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 125874181} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &125874185 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 125874181} + m_CullTransparentMesh: 1 +--- !u!1 &167076085 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 167076086} + - component: {fileID: 167076088} + - component: {fileID: 167076087} + - component: {fileID: 167076089} + m_Layer: 5 + m_Name: 12Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &167076086 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167076085} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &167076087 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167076085} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &167076088 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167076085} + m_CullTransparentMesh: 1 +--- !u!114 &167076089 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167076085} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &207043278 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 207043282} + - component: {fileID: 207043281} + - component: {fileID: 207043280} + - component: {fileID: 207043279} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &207043279 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207043278} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &207043280 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207043278} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 0.5 + m_ReferenceResolution: {x: 1920, y: 1080} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0.5 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &207043281 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207043278} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &207043282 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207043278} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1386850860} + - {fileID: 1860323809} + - {fileID: 2120814422} + - {fileID: 1197697553} + - {fileID: 125874182} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &431767752 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 431767753} + - component: {fileID: 431767755} + - component: {fileID: 431767754} + - component: {fileID: 431767756} + m_Layer: 5 + m_Name: 01Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &431767753 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 431767752} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &431767754 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 431767752} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &431767755 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 431767752} + m_CullTransparentMesh: 1 +--- !u!114 &431767756 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 431767752} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &479522083 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 479522084} + - component: {fileID: 479522086} + - component: {fileID: 479522085} + - component: {fileID: 479522087} + m_Layer: 5 + m_Name: 00Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &479522084 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 479522083} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &479522085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 479522083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &479522086 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 479522083} + m_CullTransparentMesh: 1 +--- !u!114 &479522087 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 479522083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &509870036 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 509870037} + - component: {fileID: 509870039} + - component: {fileID: 509870038} + - component: {fileID: 509870040} + m_Layer: 5 + m_Name: 21Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &509870037 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509870036} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &509870038 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509870036} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &509870039 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509870036} + m_CullTransparentMesh: 1 +--- !u!114 &509870040 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509870036} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &623150005 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 623150006} + - component: {fileID: 623150008} + - component: {fileID: 623150007} + m_Layer: 5 + m_Name: 11Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &623150006 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 623150005} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &623150007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 623150005} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &623150008 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 623150005} + m_CullTransparentMesh: 1 +--- !u!1 &674806828 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 674806831} + - component: {fileID: 674806830} + - component: {fileID: 674806829} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &674806829 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + m_Enabled: 1 +--- !u!20 &674806830 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &674806831 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &980937551 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 980937552} + - component: {fileID: 980937554} + - component: {fileID: 980937553} + - component: {fileID: 980937555} + m_Layer: 5 + m_Name: 11Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &980937552 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980937551} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &980937553 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980937551} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &980937554 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980937551} + m_CullTransparentMesh: 1 +--- !u!114 &980937555 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980937551} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &996884106 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 996884107} + - component: {fileID: 996884109} + - component: {fileID: 996884108} + - component: {fileID: 996884110} + m_Layer: 5 + m_Name: 10Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &996884107 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996884106} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &996884108 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996884106} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &996884109 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996884106} + m_CullTransparentMesh: 1 +--- !u!114 &996884110 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996884106} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &996961688 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 996961689} + - component: {fileID: 996961691} + - component: {fileID: 996961690} + - component: {fileID: 996961692} + m_Layer: 5 + m_Name: 02Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &996961689 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996961688} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &996961690 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996961688} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &996961691 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996961688} + m_CullTransparentMesh: 1 +--- !u!114 &996961692 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996961688} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1128266014 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1128266015} + - component: {fileID: 1128266017} + - component: {fileID: 1128266016} + m_Layer: 5 + m_Name: 02Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1128266015 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1128266014} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1128266016 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1128266014} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1128266017 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1128266014} + m_CullTransparentMesh: 1 +--- !u!1 &1197697552 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1197697553} + - component: {fileID: 1197697555} + - component: {fileID: 1197697554} + m_Layer: 5 + m_Name: StatusText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1197697553 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1197697552} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 192} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &1197697554 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1197697552} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Wait + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 64 + m_fontSizeBase: 64 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1197697555 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1197697552} + m_CullTransparentMesh: 1 +--- !u!1 &1361859503 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1361859504} + - component: {fileID: 1361859506} + - component: {fileID: 1361859505} + - component: {fileID: 1361859507} + m_Layer: 5 + m_Name: 22Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1361859504 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1361859503} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1361859505 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1361859503} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1361859506 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1361859503} + m_CullTransparentMesh: 1 +--- !u!114 &1361859507 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1361859503} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1386850859 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1386850860} + - component: {fileID: 1386850862} + - component: {fileID: 1386850861} + m_Layer: 5 + m_Name: ScoreText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1386850860 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1386850859} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -32} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &1386850861 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1386850859} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 0:0 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 64 + m_fontSizeBase: 64 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1386850862 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1386850859} + m_CullTransparentMesh: 1 +--- !u!1 &1427813292 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1427813293} + - component: {fileID: 1427813295} + - component: {fileID: 1427813294} + - component: {fileID: 1427813296} + m_Layer: 5 + m_Name: 20Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1427813293 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1427813292} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1427813294 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1427813292} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1427813295 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1427813292} + m_CullTransparentMesh: 1 +--- !u!114 &1427813296 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1427813292} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1495330464 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1495330465} + - component: {fileID: 1495330467} + - component: {fileID: 1495330466} + m_Layer: 5 + m_Name: 21Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1495330465 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1495330464} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1495330466 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1495330464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1495330467 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1495330464} + m_CullTransparentMesh: 1 +--- !u!1 &1748551580 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1748551581} + - component: {fileID: 1748551583} + - component: {fileID: 1748551582} + m_Layer: 5 + m_Name: 12Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1748551581 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1748551580} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1748551582 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1748551580} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1748551583 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1748551580} + m_CullTransparentMesh: 1 +--- !u!1 &1759215196 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1759215197} + - component: {fileID: 1759215199} + - component: {fileID: 1759215198} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1759215197 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1759215196} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 125874182} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1759215198 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1759215196} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Exit + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 48 + m_fontSizeBase: 48 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1759215199 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1759215196} + m_CullTransparentMesh: 1 +--- !u!1 &1782207046 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1782207047} + - component: {fileID: 1782207049} + - component: {fileID: 1782207048} + m_Layer: 5 + m_Name: 20Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1782207047 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1782207046} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1782207048 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1782207046} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1782207049 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1782207046} + m_CullTransparentMesh: 1 +--- !u!1 &1814945262 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1814945263} + - component: {fileID: 1814945265} + - component: {fileID: 1814945264} + m_Layer: 5 + m_Name: 00Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1814945263 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1814945262} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1814945264 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1814945262} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1814945265 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1814945262} + m_CullTransparentMesh: 1 +--- !u!1 &1821649078 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1821649079} + - component: {fileID: 1821649081} + - component: {fileID: 1821649080} + m_Layer: 5 + m_Name: 22Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1821649079 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1821649078} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1821649080 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1821649078} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1821649081 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1821649078} + m_CullTransparentMesh: 1 +--- !u!1 &1838535362 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1838535363} + - component: {fileID: 1838535365} + - component: {fileID: 1838535364} + m_Layer: 5 + m_Name: 01Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1838535363 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1838535362} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1838535364 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1838535362} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1838535365 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1838535362} + m_CullTransparentMesh: 1 +--- !u!1 &1860323808 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1860323809} + - component: {fileID: 1860323810} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1860323809 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1860323808} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1814945263} + - {fileID: 1838535363} + - {fileID: 1128266015} + - {fileID: 2066689120} + - {fileID: 623150006} + - {fileID: 1748551581} + - {fileID: 1782207047} + - {fileID: 1495330465} + - {fileID: 1821649079} + m_Father: {fileID: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 800, y: 800} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1860323810 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1860323808} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 4 + m_StartCorner: 0 + m_StartAxis: 0 + m_CellSize: {x: 256, y: 256} + m_Spacing: {x: 16, y: 16} + m_Constraint: 1 + m_ConstraintCount: 3 +--- !u!1 &2066689119 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2066689120} + - component: {fileID: 2066689122} + - component: {fileID: 2066689121} + m_Layer: 5 + m_Name: 10Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2066689120 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066689119} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2066689121 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066689119} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2066689122 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066689119} + m_CullTransparentMesh: 1 +--- !u!1 &2101528484 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2101528487} + - component: {fileID: 2101528486} + - component: {fileID: 2101528485} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2101528485 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101528484} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &2101528486 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101528484} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &2101528487 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101528484} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2120814421 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2120814422} + - component: {fileID: 2120814423} + m_Layer: 5 + m_Name: PlayField + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2120814422 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2120814421} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 479522084} + - {fileID: 431767753} + - {fileID: 996961689} + - {fileID: 996884107} + - {fileID: 980937552} + - {fileID: 167076086} + - {fileID: 1427813293} + - {fileID: 509870037} + - {fileID: 1361859504} + m_Father: {fileID: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 800, y: 800} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2120814423 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2120814421} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 4 + m_StartCorner: 0 + m_StartAxis: 0 + m_CellSize: {x: 256, y: 256} + m_Spacing: {x: 16, y: 16} + m_Constraint: 1 + m_ConstraintCount: 3 +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 674806831} + - {fileID: 207043282} + - {fileID: 2101528487} + - {fileID: 97341222} diff --git a/Samples~/TicTacToe/Scenes/Game.unity.meta b/Samples~/TicTacToe/Scenes/Game.unity.meta new file mode 100644 index 0000000..4bfc8c6 --- /dev/null +++ b/Samples~/TicTacToe/Scenes/Game.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 992f68042d5314a3fbbd641573b310e3 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scenes/Menu.unity b/Samples~/TicTacToe/Scenes/Menu.unity new file mode 100644 index 0000000..7bf61b1 --- /dev/null +++ b/Samples~/TicTacToe/Scenes/Menu.unity @@ -0,0 +1,3722 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &87452109 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 87452110} + - component: {fileID: 87452112} + - component: {fileID: 87452111} + m_Layer: 5 + m_Name: HostText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &87452110 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87452109} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1976736168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 128, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &87452111 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87452109} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 'Host:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &87452112 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87452109} + m_CullTransparentMesh: 1 +--- !u!1 &138338658 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 138338659} + - component: {fileID: 138338661} + - component: {fileID: 138338660} + m_Layer: 5 + m_Name: TitleText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &138338659 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138338658} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 149192843} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 508, y: 0} + m_SizeDelta: {x: 952, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &138338660 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138338658} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 64 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 6 + m_MaxSize: 64 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Wait for opponent... +--- !u!222 &138338661 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138338658} + m_CullTransparentMesh: 1 +--- !u!1 &149192842 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 149192843} + - component: {fileID: 149192846} + - component: {fileID: 149192845} + - component: {fileID: 149192844} + m_Layer: 5 + m_Name: SearchPanel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &149192843 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149192842} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 138338659} + - {fileID: 1460273542} + - {fileID: 1461035827} + - {fileID: 1655159176} + m_Father: {fileID: 1634755900} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -64, y: -64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &149192844 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149192842} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 32 + m_Right: 32 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 16 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &149192845 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149192842} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.5896226, g: 0.7976472, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &149192846 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149192842} + m_CullTransparentMesh: 1 +--- !u!1 &240390030 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 240390031} + - component: {fileID: 240390033} + - component: {fileID: 240390032} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &240390031 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 240390030} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2122295233} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &240390032 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 240390030} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "3000\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &240390033 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 240390030} + m_CullTransparentMesh: 1 +--- !u!1 &372681422 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 372681423} + - component: {fileID: 372681426} + - component: {fileID: 372681425} + - component: {fileID: 372681424} + m_Layer: 5 + m_Name: ConnectButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &372681423 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 372681422} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 982673899} + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 144} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &372681424 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 372681422} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 372681425} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 498426053} + m_TargetAssemblyTypeName: MenuController, Assembly-CSharp + m_MethodName: Connect + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &372681425 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 372681422} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &372681426 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 372681422} + m_CullTransparentMesh: 1 +--- !u!1 &447614748 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 447614749} + - component: {fileID: 447614752} + - component: {fileID: 447614751} + - component: {fileID: 447614750} + m_Layer: 5 + m_Name: PlayButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &447614749 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 447614748} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 741069091} + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 256} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &447614750 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 447614748} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 0 + m_TargetGraphic: {fileID: 447614751} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 498426053} + m_TargetAssemblyTypeName: MenuController, Assembly-CSharp + m_MethodName: Play + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &447614751 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 447614748} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &447614752 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 447614748} + m_CullTransparentMesh: 1 +--- !u!1 &459724183 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 459724184} + - component: {fileID: 459724187} + - component: {fileID: 459724186} + - component: {fileID: 459724185} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &459724184 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459724183} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 869956712} + - {fileID: 1976736168} + - {fileID: 372681423} + - {fileID: 919464296} + - {fileID: 1156390075} + - {fileID: 447614749} + - {fileID: 1016756350} + - {fileID: 1879525922} + m_Father: {fileID: 1634755900} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -64, y: -64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &459724185 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459724183} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 32 + m_Right: 32 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 16 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &459724186 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459724183} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &459724187 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459724183} + m_CullTransparentMesh: 1 +--- !u!1 &498426051 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 498426052} + - component: {fileID: 498426053} + m_Layer: 0 + m_Name: Scripts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &498426052 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 498426051} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &498426053 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 498426051} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8189a9473e61645ebb6c7b49be2df4dc, type: 3} + m_Name: + m_EditorClassIdentifier: + HostInput: {fileID: 1640573858} + PortInput: {fileID: 1564217885} + StatusText: {fileID: 1879525923} + SearchPanel: {fileID: 149192842} + PlayButton: {fileID: 447614750} +--- !u!1 &674806828 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 674806831} + - component: {fileID: 674806830} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!20 &674806830 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &674806831 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &741069090 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 741069091} + - component: {fileID: 741069093} + - component: {fileID: 741069092} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &741069091 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 741069090} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 447614749} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &741069092 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 741069090} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Play + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 96 + m_fontSizeBase: 96 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &741069093 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 741069090} + m_CullTransparentMesh: 1 +--- !u!1 &869956711 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 869956712} + - component: {fileID: 869956714} + - component: {fileID: 869956713} + m_Layer: 5 + m_Name: TitleText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &869956712 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 869956711} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &869956713 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 869956711} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 64 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 6 + m_MaxSize: 64 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Tic-Tac-Toe +--- !u!222 &869956714 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 869956711} + m_CullTransparentMesh: 1 +--- !u!1 &919464295 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 919464296} + - component: {fileID: 919464299} + - component: {fileID: 919464298} + - component: {fileID: 919464297} + m_Layer: 5 + m_Name: DisconnectButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &919464296 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 919464295} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 945034700} + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 144} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &919464297 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 919464295} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 919464298} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 498426053} + m_TargetAssemblyTypeName: MenuController, Assembly-CSharp + m_MethodName: Disconnect + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &919464298 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 919464295} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &919464299 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 919464295} + m_CullTransparentMesh: 1 +--- !u!1 &945034699 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 945034700} + - component: {fileID: 945034702} + - component: {fileID: 945034701} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &945034700 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945034699} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 919464296} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &945034701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945034699} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Disconnect + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &945034702 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945034699} + m_CullTransparentMesh: 1 +--- !u!1 &982673898 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 982673899} + - component: {fileID: 982673901} + - component: {fileID: 982673900} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &982673899 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 982673898} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 372681423} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &982673900 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 982673898} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Connect + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &982673901 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 982673898} + m_CullTransparentMesh: 1 +--- !u!1 &1016756349 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1016756350} + - component: {fileID: 1016756352} + - component: {fileID: 1016756351} + m_Layer: 5 + m_Name: 'Panel ' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1016756350 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1016756349} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1016756351 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1016756349} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1016756352 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1016756349} + m_CullTransparentMesh: 1 +--- !u!1 &1051212462 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1051212465} + - component: {fileID: 1051212464} + - component: {fileID: 1051212463} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1051212463 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1051212462} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1051212464 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1051212462} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &1051212465 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1051212462} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1075891663 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1075891664} + - component: {fileID: 1075891665} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1075891664 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1075891663} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2100409529} + - {fileID: 2129878274} + m_Father: {fileID: 1640573857} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1075891665 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1075891663} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &1078465109 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1078465110} + - component: {fileID: 1078465112} + - component: {fileID: 1078465111} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1078465110 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1078465109} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1461035827} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1078465111 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1078465109} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Cancel + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 96 + m_fontSizeBase: 96 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1078465112 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1078465109} + m_CullTransparentMesh: 1 +--- !u!1 &1156390074 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1156390075} + - component: {fileID: 1156390077} + - component: {fileID: 1156390076} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1156390075 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1156390074} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1156390076 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1156390074} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1156390077 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1156390074} + m_CullTransparentMesh: 1 +--- !u!1 &1309975583 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1309975585} + - component: {fileID: 1309975586} + m_Layer: 0 + m_Name: Connector + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1309975585 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309975583} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1309975586 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309975583} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 08c073176e63443479820504ed5e74f9, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1460273541 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1460273542} + - component: {fileID: 1460273544} + - component: {fileID: 1460273543} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1460273542 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460273541} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 149192843} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 508, y: -160} + m_SizeDelta: {x: 952, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1460273543 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460273541} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1460273544 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460273541} + m_CullTransparentMesh: 1 +--- !u!1 &1460361714 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1460361715} + - component: {fileID: 1460361718} + - component: {fileID: 1460361717} + - component: {fileID: 1460361716} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1460361715 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460361714} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2122295233} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1460361716 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460361714} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &1460361717 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460361714} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Enter text... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1460361718 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460361714} + m_CullTransparentMesh: 1 +--- !u!1 &1461035826 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1461035827} + - component: {fileID: 1461035830} + - component: {fileID: 1461035829} + - component: {fileID: 1461035828} + m_Layer: 5 + m_Name: CancelButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1461035827 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461035826} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1078465110} + m_Father: {fileID: 149192843} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 508, y: -320} + m_SizeDelta: {x: 952, y: 256} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1461035828 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461035826} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1461035829} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 498426053} + m_TargetAssemblyTypeName: MenuController, Assembly-CSharp + m_MethodName: Stop + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1461035829 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461035826} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1461035830 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461035826} + m_CullTransparentMesh: 1 +--- !u!1 &1564217883 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1564217884} + - component: {fileID: 1564217887} + - component: {fileID: 1564217886} + - component: {fileID: 1564217885} + m_Layer: 5 + m_Name: PortInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1564217884 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1564217883} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2122295233} + m_Father: {fileID: 1976736168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 144, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1564217885 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1564217883} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1564217886} + m_TextViewport: {fileID: 2122295233} + m_TextComponent: {fileID: 240390032} + m_Placeholder: {fileID: 1460361717} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 2 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 4 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 2 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: 3000 + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1564217886 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1564217883} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1564217887 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1564217883} + m_CullTransparentMesh: 1 +--- !u!1 &1634755896 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1634755900} + - component: {fileID: 1634755899} + - component: {fileID: 1634755898} + - component: {fileID: 1634755897} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1634755897 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1634755896} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1634755898 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1634755896} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 0.5 + m_ReferenceResolution: {x: 1920, y: 1080} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0.5 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1634755899 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1634755896} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1634755900 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1634755896} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 459724184} + - {fileID: 149192843} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &1640573856 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1640573857} + - component: {fileID: 1640573860} + - component: {fileID: 1640573859} + - component: {fileID: 1640573858} + m_Layer: 5 + m_Name: HostInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1640573857 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640573856} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1075891664} + m_Father: {fileID: 1976736168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 320, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1640573858 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640573856} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1640573859} + m_TextViewport: {fileID: 1075891664} + m_TextComponent: {fileID: 2129878275} + m_Placeholder: {fileID: 2100409531} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 0 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: 192.168.0.51 + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1640573859 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640573856} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1640573860 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640573856} + m_CullTransparentMesh: 1 +--- !u!1 &1655159175 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1655159176} + - component: {fileID: 1655159178} + - component: {fileID: 1655159177} + m_Layer: 5 + m_Name: 'Panel ' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1655159176 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1655159175} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 149192843} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 508, y: -480} + m_SizeDelta: {x: 952, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1655159177 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1655159175} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1655159178 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1655159175} + m_CullTransparentMesh: 1 +--- !u!1 &1879525921 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1879525922} + - component: {fileID: 1879525924} + - component: {fileID: 1879525923} + m_Layer: 5 + m_Name: StatusText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1879525922 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1879525921} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1879525923 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1879525921} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Disconnected + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1879525924 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1879525921} + m_CullTransparentMesh: 1 +--- !u!1 &1941589581 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1941589582} + - component: {fileID: 1941589584} + - component: {fileID: 1941589583} + m_Layer: 5 + m_Name: PortText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1941589582 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1941589581} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1976736168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 128, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1941589583 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1941589581} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 'Port:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1941589584 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1941589581} + m_CullTransparentMesh: 1 +--- !u!1 &1976736167 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1976736168} + - component: {fileID: 1976736169} + m_Layer: 5 + m_Name: HostPort + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1976736168 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1976736167} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 87452110} + - {fileID: 1640573857} + - {fileID: 1941589582} + - {fileID: 1564217884} + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &1976736169 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1976736167} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 3 + m_Spacing: 0 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 0 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &2100409528 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2100409529} + - component: {fileID: 2100409532} + - component: {fileID: 2100409531} + - component: {fileID: 2100409530} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2100409529 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2100409528} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1075891664} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2100409530 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2100409528} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &2100409531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2100409528} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Enter text... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2100409532 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2100409528} + m_CullTransparentMesh: 1 +--- !u!1 &2122295232 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2122295233} + - component: {fileID: 2122295234} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2122295233 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2122295232} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1460361715} + - {fileID: 240390031} + m_Father: {fileID: 1564217884} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2122295234 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2122295232} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &2129878273 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2129878274} + - component: {fileID: 2129878276} + - component: {fileID: 2129878275} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2129878274 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2129878273} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1075891664} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2129878275 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2129878273} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "192.168.0.51\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2129878276 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2129878273} + m_CullTransparentMesh: 1 +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 674806831} + - {fileID: 1634755900} + - {fileID: 1051212465} + - {fileID: 1309975585} + - {fileID: 498426052} diff --git a/Samples~/TicTacToe/Scenes/Menu.unity.meta b/Samples~/TicTacToe/Scenes/Menu.unity.meta new file mode 100644 index 0000000..9560e20 --- /dev/null +++ b/Samples~/TicTacToe/Scenes/Menu.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0a23420e63fbd4762b6af6e6609d8179 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts.meta b/Samples~/TicTacToe/Scripts.meta new file mode 100644 index 0000000..d34bbe4 --- /dev/null +++ b/Samples~/TicTacToe/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c64238bd0f8524ce7b799ebc28e587f6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/Connector.cs b/Samples~/TicTacToe/Scripts/Connector.cs new file mode 100644 index 0000000..f728e27 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/Connector.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using Shardy; + +[DefaultExecutionOrder(-1)] +public class Connector : MonoBehaviour { + + /// + /// Client instance + /// + static Client _client = null; + + /// + /// Init + /// + /// This demo uses TCP transport for connecting to test game server + /// + void Awake() { + if (_client == null) { + _client = new Client(new TestHandshake(), new TestSerializer(), new ClientOptions()); + DontDestroyOnLoad(gameObject); + } + } + + /// + /// Get client instance for external use + /// + public static Client Use() { + return _client; + } +} \ No newline at end of file diff --git a/Samples~/TicTacToe/Scripts/Connector.cs.meta b/Samples~/TicTacToe/Scripts/Connector.cs.meta new file mode 100644 index 0000000..695c61c --- /dev/null +++ b/Samples~/TicTacToe/Scripts/Connector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08c073176e63443479820504ed5e74f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/Consts.cs b/Samples~/TicTacToe/Scripts/Consts.cs new file mode 100644 index 0000000..22d4cfc --- /dev/null +++ b/Samples~/TicTacToe/Scripts/Consts.cs @@ -0,0 +1,42 @@ +public class Consts { + + /// + /// Menu scene name + /// + public const string MENU_SCENE = "Menu"; + + /// + /// Game scene name + /// + public const string GAME_SCENE = "Game"; + + /// + /// Start search command + /// + public const string SEARCH_START = "start"; + + /// + /// Stop search command + /// + public const string SEARCH_STOP = "stop"; + + /// + /// Exit game command + /// + public const string EXIT_GAME = "exit"; + + /// + /// Turn command + /// + public const string TURN = "turn"; + + /// + /// Game round command + /// + public const string ROUND = "round"; + + /// + /// Game created command, ready for play + /// + public const string PLAY = "play"; +} \ No newline at end of file diff --git a/Samples~/TicTacToe/Scripts/Consts.cs.meta b/Samples~/TicTacToe/Scripts/Consts.cs.meta new file mode 100644 index 0000000..aff0569 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/Consts.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6bd755974cd14a519727dd7cd6e87d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/GameController.cs b/Samples~/TicTacToe/Scripts/GameController.cs new file mode 100644 index 0000000..d5ea5ba --- /dev/null +++ b/Samples~/TicTacToe/Scripts/GameController.cs @@ -0,0 +1,246 @@ +using System; +using System.Text; +using NiceJson; +using TMPro; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UI; + +/// +/// Type of player' game item +/// +public enum ItemType { + Cross, + Circle, + None +} + +/// +/// Game info structure +/// +public struct GameInfo { + + /// + /// Current game id + /// + public string GameId; + + /// + /// Current player id + /// + public int PlayerId; + + /// + /// Current turn player id + /// + public int TurnPlayerId; + + /// + /// Score data + /// + public int[] Score; +} + +public class GameController : MonoBehaviour { + + /// + /// Sprites count in row + /// + const int ROW_MAX_COUNT = 3; + + /// + /// Container with game sprites + /// + [SerializeField] + Transform PlayField = null; + + /// + /// Link to cross sprite + /// + [SerializeField] + Sprite CrossIcon = null; + + /// + /// Link to circle sprite + /// + [SerializeField] + Sprite CircleIcon = null; + + /// + /// Link to cross color picker + /// + [SerializeField] + Color CrossColor = Color.red; + + /// + /// Link to circle color picker + /// + [SerializeField] + Color CircleColor = Color.green; + + /// + /// Link to score text + /// + [SerializeField] + TextMeshProUGUI ScoreText = null; + + /// + /// Link to status text + /// + [SerializeField] + TextMeshProUGUI StatusText = null; + + /// + /// Sprites in grid + /// + readonly Image[,] _field = new Image[ROW_MAX_COUNT, ROW_MAX_COUNT]; + + /// + /// Current game info + /// + GameInfo _info = new GameInfo(); + + /// + /// Init + /// + void Awake() { + var images = PlayField.GetComponentsInChildren(); + var i = 0; + for (var x = 0; x < ROW_MAX_COUNT; x++) { + for (var y = 0; y < ROW_MAX_COUNT; y++) { + _field[x, y] = images[i]; + var button = images[i].GetComponent(); + button.Init(this, x, y); + i++; + } + } + Clear(); + SetStatus("Wait, please..."); + Connector.Use().On(Consts.ROUND, (response) => { + var json = Encoding.UTF8.GetString(response.Data); + try { + var data = (JsonObject)JsonNode.ParseJsonString(json); + _info.GameId = data["g"]; + _info.PlayerId = data["p"]; + _info.TurnPlayerId = data["t"]; + _info.Score = new int[] { data["s"][0], data["s"][1] }; + } catch (Exception e) { + Debug.LogException(e); + } + Clear(); + SetScore(); + var status = _info.PlayerId != _info.TurnPlayerId ? "Wait for the opponent's step" : "Make your step"; + SetStatus(status); + }); + Connector.Use().On(Consts.TURN, (response) => { + var json = Encoding.UTF8.GetString(response.Data); + try { + var data = (JsonObject)JsonNode.ParseJsonString(json); + SetItem(data["x"], data["y"], (ItemType)(int)data["t"]); + _info.TurnPlayerId = data["t"] == 0 ? 1 : 0; + } catch (Exception e) { + Debug.LogException(e); + } + var status = _info.PlayerId != _info.TurnPlayerId ? "Wait for the opponent's step" : "Make your step"; + SetStatus(status); + }); + Connector.Use().On(Consts.EXIT_GAME, (response) => { + SetStatus("Opponent has left the game"); + }); + } + + /// + /// Unsubscrive + /// + void OnDisable() { + Connector.Use().Off(Consts.ROUND); + Connector.Use().Off(Consts.TURN); + Connector.Use().Off(Consts.EXIT_GAME); + } + + /// + /// Clear play field + /// + void Clear() { + for (var x = 0; x < ROW_MAX_COUNT; x++) { + for (var y = 0; y < ROW_MAX_COUNT; y++) { + SetItem(x, y, ItemType.None); + } + } + } + + /// + /// Set score + /// + void SetScore() { + ScoreText.text = $"{_info.Score[0]}:{_info.Score[1]}"; + } + + /// + /// Set status message + /// + /// Message text + void SetStatus(string message) { + StatusText.text = message; + } + + /// + /// Exit from game + /// + public void Exit() { + var json = new JsonObject(); + json["g"] = _info.GameId; + json["p"] = _info.PlayerId; + var data = Encoding.UTF8.GetBytes(json.ToJsonString()); + Connector.Use().Request(Consts.EXIT_GAME, data, (data) => { + SceneManager.LoadScene(Consts.MENU_SCENE); + }); + } + + /// + /// Set play item + /// + /// X coordinate + /// Y coordinate + /// Type of item + public void SetItem(int x, int y, ItemType type) { + switch (type) { + case ItemType.Cross: + _field[x, y].color = CrossColor; + _field[x, y].sprite = CrossIcon; + break; + case ItemType.Circle: + _field[x, y].color = CircleColor; + _field[x, y].sprite = CircleIcon; + break; + case ItemType.None: + _field[x, y].color = Color.white; + _field[x, y].sprite = null; + break; + default: + break; + } + } + + /// + /// Make game step + /// + /// X coordinate + /// Y coordinate + public void MakeTurn(int x, int y) { + if (_info.PlayerId != _info.TurnPlayerId) { + return; + } + var json = new JsonObject(); + json["g"] = _info.GameId; + json["p"] = _info.PlayerId; + json["x"] = x; + json["y"] = y; + var data = Encoding.UTF8.GetBytes(json.ToJsonString()); + Connector.Use().Request(Consts.TURN, data, (response) => { + if (!string.IsNullOrEmpty(response.Error)) { + SetStatus(response.Error); + } + }); + } +} diff --git a/Samples~/TicTacToe/Scripts/GameController.cs.meta b/Samples~/TicTacToe/Scripts/GameController.cs.meta new file mode 100644 index 0000000..1a84652 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/GameController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ad76e2a6f3bc4bb5a80c3869758dc7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/ItemButton.cs b/Samples~/TicTacToe/Scripts/ItemButton.cs new file mode 100644 index 0000000..3e79db7 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/ItemButton.cs @@ -0,0 +1,39 @@ +using UnityEngine; +using UnityEngine.EventSystems; + +public class ItemButton : MonoBehaviour, IPointerClickHandler { + + /// + /// Cache controller + /// + GameController _controller = null; + + /// + /// Cached X coordinate + /// + int _x = -1; + + /// + /// Cached Y coordinate + /// + int _y = -1; + + /// + /// Init item button + /// + /// Parent controller + /// X coord + /// Y coord + public void Init(GameController controller, int x, int y) { + _controller = controller; + _x = x; + _y = y; + } + + /// + /// Action on click + /// + public void OnPointerClick(PointerEventData data) { + _controller.MakeTurn(_x, _y); + } +} diff --git a/Samples~/TicTacToe/Scripts/ItemButton.cs.meta b/Samples~/TicTacToe/Scripts/ItemButton.cs.meta new file mode 100644 index 0000000..7549a98 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/ItemButton.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59dcb2c69516748f0a455ea71d5c1c3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/MenuController.cs b/Samples~/TicTacToe/Scripts/MenuController.cs new file mode 100644 index 0000000..ee0df2e --- /dev/null +++ b/Samples~/TicTacToe/Scripts/MenuController.cs @@ -0,0 +1,136 @@ +// +// This is simple game client for Tic-Tac-Toe game +// You can get game server source code here: https://github.com/mopsicus/shardy-tictactoe +// + +using UnityEngine; +using Shardy; +using TMPro; +using UnityEngine.UI; +using UnityEngine.SceneManagement; + +public class MenuController : MonoBehaviour { + + /// + /// Input field for host + /// + [SerializeField] + TMP_InputField HostInput = null; + + /// + /// Input field for port + /// + [SerializeField] + TMP_InputField PortInput = null; + + /// + /// Link to status text + /// + [SerializeField] + TextMeshProUGUI StatusText = null; + + /// + /// Search panel + /// + [SerializeField] + GameObject SearchPanel = null; + + /// + /// Play button + /// + [SerializeField] + Button PlayButton = null; + + /// + /// Init + /// + void Awake() { + Connector.Use().OnConnect += OnConnect; + Connector.Use().OnDisconnect += OnDisconnect; + Connector.Use().OnReady += OnReady; + Connector.Use().On(Consts.PLAY, (data) => { + SceneManager.LoadScene(Consts.GAME_SCENE); + }); + if (Connector.Use().IsConnected) { + PlayButton.interactable = true; + StatusText.text = "Ready for play"; + } + } + + /// + /// Unsubscribe on exit + /// + void OnDisable() { + Connector.Use().OnConnect -= OnConnect; + Connector.Use().OnDisconnect -= OnDisconnect; + Connector.Use().OnReady -= OnReady; + Connector.Use().Off(Consts.PLAY); + } + + /// + /// Callback on ready to work + /// + void OnReady() { + StatusText.text = "Ready for play"; + } + + /// + /// Callback on disconnect with reason + /// + void OnDisconnect(DisconnectReason reason) { + PlayButton.interactable = false; + StatusText.text = $"Disconnected: {reason}"; + } + + /// + /// Callback on connect with status + /// + void OnConnect(bool status) { + PlayButton.interactable = status; + StatusText.text = status ? "Connected" : "Disconnected"; + if (status) { + Connector.Use().Handshake(); + } + } + + /// + /// Connect to server + /// + public void Connect() { + var host = HostInput.text.Trim(); + var port = int.Parse(PortInput.text.Trim()); + Connector.Use().Connect(host, port); + } + + /// + /// Disconnect + /// + public void Disconnect() { + Connector.Use().Disconnect(); + } + + /// + /// Start play + /// + public void Play() { + SearchPanel.SetActive(true); + Connector.Use().Request(Consts.SEARCH_START, (data) => { + if (!string.IsNullOrEmpty(data.Error)) { + SearchPanel.SetActive(false); + StatusText.text = data.Error; + } + }); + } + + /// + /// Stop opponent search + /// + public void Stop() { + Connector.Use().Request(Consts.SEARCH_STOP, (data) => { + if (!string.IsNullOrEmpty(data.Error)) { + StatusText.text = data.Error; + } + SearchPanel.SetActive(false); + }); + } +} diff --git a/Samples~/TicTacToe/Scripts/MenuController.cs.meta b/Samples~/TicTacToe/Scripts/MenuController.cs.meta new file mode 100644 index 0000000..b2f6706 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/MenuController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8189a9473e61645ebb6c7b49be2df4dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/TestHandshake.cs b/Samples~/TicTacToe/Scripts/TestHandshake.cs new file mode 100644 index 0000000..3a2e4ec --- /dev/null +++ b/Samples~/TicTacToe/Scripts/TestHandshake.cs @@ -0,0 +1,38 @@ +using System.Text; +using Shardy; + +/// +/// Handshake stub +/// +class TestHandshake : IValidator { + + /// + /// Data for acknowledgement + /// + public byte[] Acknowledgement(byte[] body) { + // + // generate as you wish here + // + return body; + } + + /// + /// Data for initial handshake + /// + public byte[] Handshake(byte[] body = null) { + // + // generate as you wish here + // + return Encoding.UTF8.GetBytes("handshake_data"); + } + + /// + /// Verify acknowledgement + /// + public ValidatorState VerifyAcknowledgement(byte[] body) { + // + // validate as you wish here + // + return ValidatorState.Success; + } +} \ No newline at end of file diff --git a/Samples~/TicTacToe/Scripts/TestHandshake.cs.meta b/Samples~/TicTacToe/Scripts/TestHandshake.cs.meta new file mode 100644 index 0000000..ac63c1c --- /dev/null +++ b/Samples~/TicTacToe/Scripts/TestHandshake.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00986864a3f414c5fb448a110b260636 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/TestSerializer.cs b/Samples~/TicTacToe/Scripts/TestSerializer.cs new file mode 100644 index 0000000..503cb7f --- /dev/null +++ b/Samples~/TicTacToe/Scripts/TestSerializer.cs @@ -0,0 +1,30 @@ +using System.Text; +using NiceJson; +using Shardy; + +/// +/// Simple example serializer via NiceJson +/// +class TestSerializer : ISerializer { + + /// + /// Decode received data to PayloadData + /// + public PayloadData Decode(byte[] body) { + var data = (JsonObject)JsonNode.ParseJsonString(Encoding.UTF8.GetString(body)); + return new PayloadData((PayloadType)(int)data["type"], data["name"], data["id"], Encoding.UTF8.GetBytes(data["data"]), data["error"]); + } + + /// + /// Encode to byte array for transporting + /// + public byte[] Encode(PayloadData payload) { + var data = new JsonObject(); + data["type"] = (int)payload.Type; + data["name"] = payload.Name; + data["id"] = payload.Id; + data["data"] = (payload.Data != null) ? Encoding.UTF8.GetString(payload.Data) : string.Empty; + data["error"] = payload.Error; + return Encoding.UTF8.GetBytes(data.ToJsonString()); + } +} \ No newline at end of file diff --git a/Samples~/TicTacToe/Scripts/TestSerializer.cs.meta b/Samples~/TicTacToe/Scripts/TestSerializer.cs.meta new file mode 100644 index 0000000..281df04 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/TestSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 46dd4829a45134c1cad76cafce5a775d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json new file mode 100644 index 0000000..e4e6cbf --- /dev/null +++ b/package.json @@ -0,0 +1,43 @@ +{ + "name": "com.mopsicus.shardy", + "version": "1.0.0", + "displayName": "Shardy", + "description": "Client for Shardy – framework for online games and applications for Node.js. Supports sockets, websockets, WebGL.", + "license": "MIT", + "author": "Mopsicus ", + "homepage": "https://github.com/mopsicus/shardy-unity", + "changelogUrl": "https://github.com/mopsicus/shardy-unity/blob/main/CHANGELOG.md", + "documentationUrl": "https://github.com/mopsicus/shardy-unity/blob/main/Documentation~/index.md", + "unity": "2022.3", + "keywords": [ + "shardy", + "framework", + "rpc", + "web", + "netcode", + "games", + "engine", + "multiplayer", + "websocket", + "networking", + "webgl", + "socket" + ], + "dependencies": {}, + "repository": { + "type": "git", + "url": "https://github.com/mopsicus/shardy-unity.git" + }, + "samples": [ + { + "displayName": "Demo", + "description": "A demo scene to show Shardy API usage", + "path": "Samples~/Demo" + }, + { + "displayName": "TicTacToe", + "description": "Tic-Tac-Toe client for test game server ", + "path": "Samples~/TicTacToe" + } + ] + } \ No newline at end of file diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..65411ff --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cbdfae54d471141ab8c6fbe89f744f05 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: