Code Monkey home page Code Monkey logo

resultadosdigitais / matrix Goto Github PK

View Code? Open in Web Editor NEW
900.0 178.0 237.0 9.27 MB

#matrix is the online open-source workplace inspired in sococo.com for distributed teams to have the experience of work together each day, side-by-side. No matter where team members might be. Working in an online workplace is even more productive when people are feeling in the same space.

License: MIT License

JavaScript 96.97% Dockerfile 0.73% CSS 0.94% Shell 0.53% EJS 0.83%
workspace work-from-home hacktoberfest

matrix's Introduction

#matrix

Online open-source workplace for distributed teams.

CircleCI Status chat on Slack

Welcome to the #matrix

The objective of #matrix project is to provide a virtual office environment like in a physical office. When we are working in a physical office, it's very common to go from one room to another to meet people and have conversations, for example: kitchen, lounge, gaming room, etc.

When working remotely there is less interaction with other members of your team like in a physical office. The #matrix project was born as a proposal to improve that experience. The idea is to allow you to create several virtual rooms mimicking the real world where people can enter an room.

#matrix creates a virtual office for remote teams. Read more on this post in Medium.

Matrix Home Screenshot

Table of Contents

Understanding #matrix

Rooms

When you are inside of the #matrix you will see several rooms. Because there is no way to actually see the person you can't tell if they are on a meeting or phone call. To help with that, we show a headset icon around their avatar. In the image below you can see that people in the Platform-Email room are in a meeting.

Office Page With Sidebar

Availability And Meetings

#matrix is a virtual environment office, so you can show you are available for the other on enter in a room through the ENTER ROOM button. This is like "Hey, I am here in the office". Or you can enter in a meeting through the button ENTER MEETING.

The embeded meet is provided by meet.jit.si service and this service is maintained by the Jitsi team at 8x8. Access the jitsi GitHub and learn more about this amazing video bridge service. You can change that using external meet option in any room.

Meeting Room With Sidebar

Installation

Environment Variables

The #matrix project has some environment variables that important to define.

  • We are using Google to authorizations, you only need to configure the Google API credentials following this step by step and after define these variables:

      GOOGLE_CLIENT_ID=${paste_your_client_id_here}
      GOOGLE_SECRET={paste_your_secret_here}
      GOOGLE_CALLBACK_URL=http://localhost:8080/auth/google/callback
    

    Note: if you used version 1, with variable GOOGLE_CREDENTIAL, follow this guide

  • You can change the secret and maximum age from session:

      COOKIE_SESSION_SECRET=matrix-session
      COOKIE_SESSION_MAX_AGE=2592000000
    
  • You can define a white List of trusted email domains can enter in the #matrix

      WHITELIST_DOMAINS=["domain1.com","domain2.com"]
    
  • If you are running with ssl It's important to configure SSL, to define this:

      ENFORCE_SSL=true
    
  • The #matrix needs to know, where it get rooms definitions:

      ROOMS_SOURCE=ENVIRONMENT | REMOTE
    
  • There is a config that define the rooms of The #matrix, If you want to customize your rooms or add and a new room, you have to configure a ROOMS_SOURCE=ENVIRONMENT and config ROOMS_DATA like the example:

      ROOMS_DATA=[
         {
            "id":"${UUID}",
            "name":"Lounge",
            "disableMeeting":true
         },
         {
            "id":"${UUID}",
            "name":"WAR ROOM CDP",
        "description": "Welcome to the WAR room"
         },
         {
            "id":"${UUID}",
            "name":"Data Services",
      	  "externalMeetUrl": "https://external-url-room/key-room"
         }
       ]
    

Another option is to have a remote rooms config file (this file needs to be accessible via http/s). You can configure a ROOMS_SOURCE=REMOTE and config ROOMS_DATA like the example:

	ROOMS_DATA=https://myfilelocation.io/myrooms_data.json

External Meet

The embeded meet is provided by meet.jit.si service, but you can change that in any room, using serices like Meet or Zoom. For that, you just need provide the parameter externalMeetUrl in your room config:

	ROOMS_DATA=[
	   {
	      "id":"${UUID}",
	      "name":"Meeting External",
	      "externalMeetUrl": "https://external-url-room/key-room"
	   }
	 ]

Authentication

The login is so simple. You only need to configure the Google API credentials following this step by step .

Login Login in Dark Mode

Docker Compose

If you want run the #matrix, you need docker-compose and follow steps:

  1. Clone this repository git clone [email protected]:ResultadosDigitais/matrix.git

  2. We are using Google to authorizations, you need create a credential here you can follow step by step

  3. duplicate file variables.example.env and rename to variables.env, after that set your environment variables;

  4. Run application with docker compose:

     $ docker-compose up
    
  5. Open your browser and access:

     http://localhost:8080/
    
  6. When you finish, you can run:

     $ docker-compose down
    

On GCP

If you prefer, you can run #matrix on GCP:

Run on Google Cloud

On Heroku

If you prefer, you can run #matrix in Heroku:

Deploy

On Kubernetes

It is possible to run #matrix on Kubernetes, what you need to have is a running cluster and a Docker repository to fetch image from.

Example files can be found in docs/kubernetes/. Copy the files and follow the instructions bellow:

  1. Change the values for MATRIX_IMG and MATRIX_TAG in deployment.yaml
  2. Adjust the GOOGLE_CALLBACK_URL
  3. Add your Google Credentials in credentials.env and create the secret with
     kubectl create secret generic matrix-credentials --from-env-file=env_credentials
  4. Create you rooms.json file and create a config map with
    kubectl create configmap matrix-rooms --from-file=rooms.json
  5. Apply the services and deployment files
    kubectl apply -f deployment.yaml
    kubectl apply -f service.yaml

Currently the service is using a LoadBalancer, it is possible to change to ClusterIP and use it behind an Ingress as well. Also note that in the example we are using HTTP, it is highly recommended to use HTTPS instead!

If you are using HTTPS, do change ENFORCE_SSL to true and add your company domain to WHITELIST_DOMAINS.

Production concerns

If you will run in production we strongly recommend you close your environment using an internal VPN. In this solution everybody with the link and a valid google credential can enter your virtual office. Because this is important for you to maintain your environment closed. Or you can define a variable WHITELIST_DOMAINS to limit only authorized users to enter in the #matrix. You have to choose a strong key to the COOKIE_SESSION_SECRET and have to put in GOOGLE_CALLBACK_URL your production domain.

	WHITELIST_DOMAINS=["domain1.com","domain2.com"]

If you can't use a VPN or don't have a custom domain for your users, and you still want to restrict access to the #matrix, you can define a WHITELIST_USERS variable to create an array of trusted e-mails that can access your virtual office.

	WHITELIST_USERS=["[email protected]","[email protected]"]

Versions

Version Name Description Docs
Latest upcoming small improvements changelog
2.0.0 Seraph New authentication Migration guide to 2.0.0
1.1.0 Morpheus New layout Pull request
1.0.0 Neo The one project -

Please read more details about our versions folowing changelog file.

Frequently Asked Questions

Some questions come up over and over again. Check here first: FAQ

Get in Touch

There are several ways to get in touch with us:

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Juliemar Berri

📝 💻 🚧 📖 📢

Bruno Nardini

💻 🚧 📖

Alessandro Tegner

💻 🚧 🚇

Rogerio Angeliski

💻 🚧 📖

Diogo Nicoleti

💻

Ricardo F. Verhaeg

📖

Natalia Favareto

💻

João Ernesto Arzamendia

💻

Guilherme Nogara

💻

Phiter Fernandes

💻

Silvana Lima

💻

This project follows the all-contributors specification. Contributions of any kind welcome!

Everyone interacting in #matrix codebase, issue trackers, chat rooms, and mailing lists is expected to follow code of conduct.

License

The #matrix is released under the MIT License

"The answer is out there, Neo, and it's looking for you, and it will find you if you want it to."

matrix's People

Contributors

allcontributors[bot] avatar angeliski avatar capybot avatar dependabot-preview[bot] avatar diegocsandrim avatar diogonicoleti avatar drgomesp avatar dvinciguerra avatar enieber avatar felipecdo avatar guilhermeeric avatar hashtegner avatar helderberto avatar henrylle avatar hudolfhess avatar jarzamendia avatar jeantoledo avatar jeveaux avatar joaohornburg avatar jorgemdnt avatar juliemar avatar lcezermf avatar lgiacomini92 avatar megatroom avatar otherpirate avatar pedroo123 avatar phiter avatar raphaellnascimento avatar rd-systems avatar silvanavlima avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

matrix's Issues

Firefox home page issue

Description

This is a UX/UI issue that make side panel to not complete height screen 100%.

Steps to Reproduce

UA:
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0

Browser:
Firefox v67

Address:
https://secret-tundra-49376.herokuapp.com/

Expected Behavior

image

Current Behavior

image

Possible Solution

Adding a simple class h-100 to a parent div.row seems to fix the problem.

    <div class="container-fluid">
        <div class="row h-100">
            <div class="col-md-3 login_panel">
                <div class="row h-100 justify-content-center align-items-center">
...

Salas no jitsi estão publicas

O jitsi por padrão cria as salas publicas e por este motivo qualquer usuario pode ir na home e descobri o nome da sala que estamos utilizando no matrix. Ex:
matrix-jitsi

Authentication error for already logged in user

It's not showing my user avatar in room and my login in app bar.

Description

When I enter the Matrix, my profile picture and my login it's not showing:

matrix-bug

I'm already logged in, 'cause when I enter in login I'm redirected to morpheus page like the printscreen above.

My local storage:

Key Value
roomId df1c36dc-a1e6-4ba3-bd22-672434c5cd6a
user {"id":"107191581624534844620","email":"[email protected]"}

I try to run Matrix locally and it works.

Possible Solution

I suggest to start looking in the authentication validator.

Ability to create private rooms

Description

Currently, all the rooms are public. Users should be able to create private rooms or make private a public room and manage who can access these rooms

Describe alternatives you've considered

  1. Users should be able to create private rooms or make private a public room
  2. The users can invite other users to the room
  3. An uninvited user cannot access the private rooms
  4. An uninvited user can request access to the private rooms
  5. People in the private room can approve/deny join requests

Youtube sharing video feature only works with who shares

Description

Quando compartilho um vídeo do Youtube 
       usando a feature de compartilhamento de vídeo no youtube
Então eu consigo dar play e ouvir o som do vídeo compartilhado
Quando alguém da sala compartilha um vídeo do Youtube 
       usando a feature de compartilhamento de vídeo no youtube
Então vejo uma imagem congelada do vídeo compartilhado
E não consigo dar play e ouvir o som do vídeo
Quando alguém da sala compartilha um vídeo do Youtube 
       usando a feature de compartilhamento de vídeo no youtube
E deixam param de compartilhar o vídeo
Então continuo vendo a imagem congelada do vídeo compartilhado
E não consigo dar play e ouvir o som do vídeo
E nem sair do compartilhamento. Aparece como se ainda estivesse compartilhado

Room's modal has default title

Description

Room's modal has default title Modal title.

Steps to Reproduce

  1. Enter the SBT room
  2. Join the call

Expected Behavior

  • The modal title must be SBT (room name)

Current Behavior

  • The modal title is Modal title
    image

Ability to change room name and designate a description

Description

Ability for someone to change a room name and add a description of what is being worked on on that room.

This will help people to join the correct rooms without the need of an external message, like Slack.

Be able to get an user into the current room

Description

As a matrix user I want to get a user into the room I am, so I can easily communicate with him.

User case

I click with the rigth button in the person and choose the option "Get Paul".
Paul receives a notification saying that I want to talk to him.
Paul clicks in Ok button, and is redirected to the room

right click to get user in meet doesn't work

Description

When I want to get a user to my room and this user is in the meeting in another room the right click menu "Get" don't work.

Steps to Reproduce

  1. Stay logged with 2 users
  2. enter in the room with user A and start a Meet
  3. With user B in a different room try to execute right click on the User A avatar.

Expected Behavior

  • expected to appear the Get menu
    image

Current Behavior

  • current behavior appears only the native browser context menu
    image

I am available to talk room

Description

As a user, it would be great if there is a room which I can go and do not open a meeting.
This can be a Team Room or a I am available room

It is annoying everytime that I select a room, open a meeting, even when I am only available for call (not in a meeting)

Add Hability to Minimize the Modal Meeting View

It would be nice if the modal view has capability to be minimized or resized.

When user is in the meeting he cannot see the rooms to see if a user is available to call him to enter in the meeting.

Play a sound when exit the call

Quando eu estiver em uma call
E alguém sair ou entrar em uma call
Então eu ouço um som caracteristico de que alguem saiu/entrou porém muito baixo

Uma alteração bacana seria deixar esse som característico mais alto

configuration ROOMS_DATA in heroku

This project is very nice and I go start test, but I don't how to set default rooms data environment, because in Setup is only in JSON/JS format

When the user is in meet "title" with the user name doesn't appear

Description

When the user is in meet "title" with the user name doesn't appear

Steps to Reproduce

  1. When the user is in meet stop mouse pointer on the user avatar

Expected Behavior

  • expected appear title or tooltip with the user name
    image

Current Behavior

  • nothing happens
    image

enable HTTP protocol redirect

Description

When I'm using my environment in HTTPS on Heroku and user access via HTTP the user is not redirected from HTTP to HTTPS and the consequence is a google login error

Steps to Reproduce

  1. Deploy #matrix on Heroku
  2. Configure Google login for HTTPs Heroku URI
  3. access #matrix in HTTP
  4. try to login

Expected Behavior

  • expected behavior redirect #matrix URI to Https

Current Behavior

  • current behavior the user receives the google login error because the protocol is not matched with the google login stored

Possible Solution

Insert Google oauth url callback in README.md

Insert Google oauth url callback in README.md

Description

Guys, could you please add what is the Google oauth url callback in README.md? I'm trying to deploy Matrix but I cannot find this information.

Thanks in advance!

Bug ao usar a câmera do Macbook

Description

Pessoal, em todas as salas que entramos com o Macbook a tela do Jitsu fica cortada. Nos outros dispositivos que testamos isso não acontece.

Alguns testes já realizados realizados:

  • Se acessar o Jitsu por fora da Matrix tudo funciona normalmente.
  • Se entrar na sala na Matrix, pegar o link da sala e logar por fora da Matrix tudo funciona normalmente.

Steps to Reproduce

  1. Acesse a Matrix com um Macbook
  2. Entre em uma sala e ligue a câmera do notebook.

Expected Behavior

  • A imagem da câmera ser mostrada normalmente, sem cortes na tela.

Current Behavior

  • A imagem da câmera é mostrada com um corte, na parte de cima e na parte de baixo. Algo como widescreen.

Possible Solution

  • Verificar se na api do Jitsi tem algum parâmetro que pode causar esse comportamento.

Reserved Meeting Room

As a user, I would like to have a reserved meeting room and add it to Invitation in my Google Calendar

Description

Currently, Matrix does not allow any reserved room.
If I am planning a meeting and I would like to send a Calendar Invitation I can't ensure that current rooms will be available for meeting at desired date and time, making it hard to send a matrix URL.

Suggested approaches:

Reserved Room

As in real life situations, I can create a reserved room and the desired one will be available for meeting by kicking out the current people in the room and make it free to the reserved conference call.

Unique Temporary Rooms

As usually happens in other communication tools, I can have a room unique UUID. When there is any user in that space, it is available for other people enter and use it. When there is not, It is deleted from the Matrix Map.

"Cannot find module" error on docker-compose

Hi!

I'm receiving the follow error when trying to start the matrix:

Recreating matrix_web_1 ... done
Attaching to matrix_web_1
web_1  | 
web_1  | > matrix-backend@ start-backend /var/app/backend
web_1  | > NODE_ENV=production node ./dist/index.js
web_1  | 
web_1  | internal/modules/cjs/loader.js:638
web_1  |     throw err;
web_1  |     ^
web_1  | 
web_1  | Error: Cannot find module '/var/app/backend/dist/index.js'
web_1  |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
web_1  |     at Function.Module._load (internal/modules/cjs/loader.js:562:25)
web_1  |     at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
web_1  |     at startup (internal/bootstrap/node.js:283:19)
web_1  |     at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
web_1  | npm ERR! code ELIFECYCLE
web_1  | npm ERR! errno 1
web_1  | npm ERR! matrix-backend@ start-backend: `NODE_ENV=production node ./dist/index.js`
web_1  | npm ERR! Exit status 1
web_1  | npm ERR! 
web_1  | npm ERR! Failed at the matrix-backend@ start-backend script.
web_1  | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
web_1  | npm WARN Local package.json exists, but node_modules missing, did you mean to install?

Steps to Reproduce

I changed the docker-compose.yml file to add the environments variables, like:

version: '3'
services:
  web:
    environment:
      GOOGLE_CREDENTIAL: '565689845454-asdas8789asdjasjkdhop.apps.googleusercontent.com'
      ENFORCE_SSL: 'true'
      ROOMS_DATA: '[{"id": "4bc05520-32a2-42ea-9c24-138f154e6c11", "name": "Lounge", "disableMeeting":true}, {"id": "4bc05520-32a2-42ea-9c24-138f154e6c12", "name": "WAR ROOM CDP"}, {"id": "4bc05520-32a2-42ea-9c24-138f154e6c13", "name": "Data Services"}]'
      ROOMS_SOURCE: 'ENVIRONMENT'
    working_dir: /var/app
    ports:
     - '8080:8080'
    volumes:
      - .:/var/app
    # entrypoint: 'sh /docker-entrypoint.sh npm run start'
    build:
      context: ./

I'm trying to start the matrix using docker-compose:

docker-compose up

This error not changed with the environment variables setted or not.

I also added a RUN command to see what is inside the /var/app/backend/dist/ in the Dockerfile:

Step 11/13 : RUN ls /var/app/backend/dist/
 ---> Running in 0da97a5b0d20
app.config.js
app.routes.js
app.server.js
controllers
index.js
office.factory.js
office.socket.js

The index.js file is there.

What I'm doing wrong here?

Firefox visualization issue

Modal not showed properly in Firefox 66.0.3 (64-bit).
The height is small as one can see in the following pic:

image

Add Hability to define trusted login domains

Description

I'd like to close my office to enable only users with a trusted e-mail to enter my office.

Describe alternatives you've considered

in MVP mode we can use an environment variable with the list of trusted e-mail domains.

share room link to anothers users

Description

sometimes we need to share the room link to other users.

Expected Behavior

  • when I copy current room url and send to other user this second user should enter in the same room that I'm.

Current Behavior

  • today is not possible todo this.

Possible Solution

Sugestion: add an anchor of roomId in URL:
EX:
localhost:8080/office#room-1
localhost:8080/office#room-3

A better approach to deal with strings spread in the code

Description

We have some strings spread in the code, they're used to create the notification box that will be showed to the user.

I think we need a better approach to deal with these strings and avoid them in the middle of the code.

MAYBE something similar with Rails i18n.

Logout is not working after user sign in

Description

Logout is not working when the user clicks on Logout button.
OBS: If the user reloads the page and clicks the Logout button a few times, the logout works

Steps to Reproduce

  1. Access Matrix login page
  2. Sign in Matrix using a google account
  3. Once you have redirected to the office page, click the Logout button in the navbar

Expected Behavior

  • Your account must be disconnected and you must be redirected to the login page.

Current Behavior

  • An error occurs and logout is not working
    image

New favicon

Alterar o favicon atual (ta parecendo um botão de erro ou fechar :/ ).

Does not close the call when clicked out of call modal

Description

Quando entro em uma call
E clico fora do modal da call
Então eu saio automaticamente da call

O que poderia acontecer

Bloquear esse comportamento para não sair da call sem querer quando clicar fora do modal

Matrix is always asking the user to enter call when he enters a new room

Description

Matrix is always asking the user to enter call when he enters a new room, even though when the room does not have a call or when the room was empty.

Steps to Reproduce

  1. Open Matrix
  2. Enter in a empty room

Expected Behavior

  • I should be asked if I want to create a new call

Current Behavior

  • I'm asked if I want to enter in the call
    image

Change default route to root path

Add related routes without /morpheus prefix.

Description

The /morpheus prefix was added temporary to keep legacy until it was approved. As Morpheus became the default layout, we lost the main routes.

We can keep the prefix to avoid broken links, we can redirect to respectively root route. This will avoid to save the wrong routes and we can remove then in the feature.

The routes will be:

Morpheus URL Root URL Description
/morpheus / Redirects to Login or to Office page
/morpheus/office/<id> /office/<id> Office page
/morpheus/room/<id> /room/<id> Meeting room

Pomodoro's time

There is a concept to managing focus time called the Pomodoro time. This technique consists to dedicate a full focused time to do something. In a virtual environment is important to identify to other users that I'm in my Pomodoro time. so my suggestion Is:

I would like to start my Pomodoro time. In the matrix, I Start my Pomodoro time, my avatar starts to show a Pomodoro decorator for other logged users. In this time window, I won't receive any notification. when my Pomodoro time's finish I receive a notification and my avatar hide the Pomodoro decorator and now I'm able to receive any notification.

Create a logout option in main page

Description

Currently, Matrix does not have a logout option and its users cannot logout.

Describe alternatives you've considered

  • We need to create a logout option in main page.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.