Merge branch 'master' into dependabot/npm_and_yarn/backend/babel/preset-env-7.22.9

This commit is contained in:
mahula 2023-07-31 19:07:56 +02:00 committed by GitHub
commit 2c8009d406
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
214 changed files with 3641 additions and 1541 deletions

View File

@ -1,4 +1,5 @@
backend: &backend
- '.github/workflows/test-backend.yml'
- 'backend/**/*'
- 'neo4j/**/*'
@ -6,4 +7,5 @@ docker: &docker
- 'docker-compose.*'
webapp: &webapp
- '.github/workflows/test-webapp.yml'
- 'webapp/**/*'

View File

@ -0,0 +1,42 @@
###############################################################################
# A Github repo has max 10 GB of cache.
# https://github.blog/changelog/2021-11-23-github-actions-cache-size-is-now-increased-to-10gb-per-repository/
#
# To avoid "cache thrashing" by their cache eviction policy it is recommended
# to apply a cache cleanup workflow at PR closing to dele cache leftovers of
# the current branch:
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
###############################################################################
name: ocelot.social cache cleanup on pr closing
on:
pull_request:
types:
- closed
jobs:
clean-branch-cache:
name: Cleanup branch cache
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache
REPO=${{ github.repository }}
BRANCH="refs/pull/${{ github.event.pull_request.number }}/merge"
echo "Fetching list of cache key"
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH | cut -f 1 )
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,7 +1,7 @@
name: ocelot.social backend test CI
on: [push]
on: push
jobs:
files-changed:
@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@v3.3.0
- name: Check for frontend file changes
- name: Check for backend file changes
uses: dorny/paths-filter@v2.11.1
id: changes
with:
@ -34,12 +34,13 @@ jobs:
run: |
docker build --target community -t "ocelotsocialnetwork/neo4j-community:test" neo4j/
docker save "ocelotsocialnetwork/neo4j-community:test" > /tmp/neo4j.tar
- name: Upload Artifact
uses: actions/upload-artifact@v3
- name: Cache docker images
id: cache-neo4j
uses: actions/cache/save@v3.3.1
with:
name: docker-neo4j-image
path: /tmp/neo4j.tar
key: ${{ github.run_id }}-backend-neo4j-cache
build_test_backend:
name: Docker Build Test - Backend
@ -54,12 +55,13 @@ jobs:
run: |
docker build --target test -t "ocelotsocialnetwork/backend:test" backend/
docker save "ocelotsocialnetwork/backend:test" > /tmp/backend.tar
- name: Upload Artifact
uses: actions/upload-artifact@v3
- name: Cache docker images
id: cache-backend
uses: actions/cache/save@v3.3.1
with:
name: docker-backend-test
path: /tmp/backend.tar
key: ${{ github.run_id }}-backend-cache
lint_backend:
name: Lint Backend
@ -84,28 +86,29 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- name: Download Docker Image (Neo4J)
uses: actions/download-artifact@v3
- name: Restore Neo4J cache
uses: actions/cache/restore@v3.3.1
with:
name: docker-neo4j-image
path: /tmp
path: /tmp/neo4j.tar
key: ${{ github.run_id }}-backend-neo4j-cache
fail-on-cache-miss: true
- name: Load Docker Image
run: docker load < /tmp/neo4j.tar
- name: Download Docker Image (Backend)
uses: actions/download-artifact@v3
- name: Restore Backend cache
uses: actions/cache/restore@v3.3.1
with:
name: docker-backend-test
path: /tmp
path: /tmp/backend.tar
key: ${{ github.run_id }}-backend-cache
fail-on-cache-miss: true
- name: Load Docker Image
run: docker load < /tmp/backend.tar
- name: Load Docker Images
run: |
docker load < /tmp/neo4j.tar
docker load < /tmp/backend.tar
- name: backend | copy env files webapp
run: cp webapp/.env.template webapp/.env
- name: backend | copy env files backend
run: cp backend/.env.template backend/.env
- name: backend | copy env files
run: |
cp webapp/.env.template webapp/.env
cp backend/.env.template backend/.env
- name: backend | docker-compose
run: docker-compose -f docker-compose.yml -f docker-compose.test.yml up --detach --no-deps neo4j backend
@ -118,3 +121,20 @@ jobs:
- name: backend | Unit test incl. coverage check
run: docker-compose exec -T backend yarn test
cleanup:
name: Cleanup
if: ${{ needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.docker == 'true' }}
needs: [files-changed, unit_test_backend]
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Delete cache
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh extension install actions/gh-actions-cache
KEY="${{ github.run_id }}-backend-neo4j-cache"
gh actions-cache delete $KEY -R Ocelot-Social-Community/Ocelot-Social --confirm
KEY="${{ github.run_id }}-backend-cache"
gh actions-cache delete $KEY -R Ocelot-Social-Community/Ocelot-Social --confirm

View File

@ -1,9 +1,54 @@
name: ocelot.social end-to-end test CI
on: push
jobs:
docker_preparation:
name: Fullstack test preparation
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Copy env files
run: |
cp webapp/.env.template webapp/.env
cp backend/.env.template backend/.env
- name: Build docker images
run: |
mkdir /tmp/images
docker build --target community -t "ocelotsocialnetwork/neo4j-community:test" neo4j/
docker save "ocelotsocialnetwork/neo4j-community:test" > /tmp/images/neo4j.tar
docker build --target test -t "ocelotsocialnetwork/backend:test" backend/
docker save "ocelotsocialnetwork/backend:test" > /tmp/images/backend.tar
docker build --target test -t "ocelotsocialnetwork/webapp:test" webapp/
docker save "ocelotsocialnetwork/webapp:test" > /tmp/images/webapp.tar
- name: Install cypress requirements
run: |
wget --no-verbose -O /opt/cucumber-json-formatter "https://github.com/cucumber/json-formatter/releases/download/v19.0.0/cucumber-json-formatter-linux-386"
cd backend
yarn install
yarn build
cd ..
yarn install
- name: Cache docker images
id: cache
uses: actions/cache/save@v3.3.1
with:
path: |
/opt/cucumber-json-formatter
/home/runner/.cache/Cypress
/home/runner/work/Ocelot-Social/Ocelot-Social
/tmp/images/
key: ${{ github.run_id }}-e2e-preparation-cache
fullstack_tests:
name: Fullstack tests
if: success()
needs: docker_preparation
runs-on: ubuntu-latest
env:
jobs: 8
@ -12,28 +57,27 @@ jobs:
# run copies of the current job in parallel
job: [1, 2, 3, 4, 5, 6, 7, 8]
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Restore cache
uses: actions/cache/restore@v3.3.1
id: cache
with:
path: |
/opt/cucumber-json-formatter
/home/runner/.cache/Cypress
/home/runner/work/Ocelot-Social/Ocelot-Social
/tmp/images/
key: ${{ github.run_id }}-e2e-preparation-cache
fail-on-cache-miss: true
- name: webapp | copy env file
run: cp webapp/.env.template webapp/.env
- name: backend | copy env file
run: cp backend/.env.template backend/.env
- name: boot up test system | docker-compose
run: docker-compose -f docker-compose.yml -f docker-compose.test.yml up --detach --no-deps webapp neo4j backend
- name: Full stack tests | prepare
- name: Boot up test system | docker-compose
run: |
wget --no-verbose -O /opt/cucumber-json-formatter "https://github.com/cucumber/json-formatter/releases/download/v19.0.0/cucumber-json-formatter-linux-386"
chmod +x /opt/cucumber-json-formatter
sudo ln -fs /opt/cucumber-json-formatter /usr/bin/cucumber-json-formatter
cd backend
yarn install
yarn build
cd ..
yarn install
docker load < /tmp/images/neo4j.tar
docker load < /tmp/images/backend.tar
docker load < /tmp/images/webapp.tar
docker-compose -f docker-compose.yml -f docker-compose.test.yml up --detach --no-deps webapp neo4j backend
sleep 90s
- name: Full stack tests | run tests
id: e2e-tests
@ -44,17 +88,25 @@ jobs:
run: |
cd cypress/
node create-cucumber-html-report.js
- name: End-to-end tests | if tests failed, get pr number
id: pr
if: ${{ failure() && steps.e2e-tests.conclusion == 'failure' }}
uses: 8BitJonny/gh-get-current-pr@2.2.0
- name: End-to-end tests | if tests failed, upload report
- name: Full stack tests | if tests failed, upload report
id: e2e-report
if: ${{ failure() && steps.e2e-tests.conclusion == 'failure' }}
uses: actions/upload-artifact@v3
with:
name: ocelot-e2e-test-report-pr${{ steps.pr.outputs.number }}
name: ocelot-e2e-test-report-pr${{ needs.docker_preparation.outputs.pr-number }}
path: /home/runner/work/Ocelot-Social/Ocelot-Social/cypress/reports/cucumber_html_report
cleanup:
name: Cleanup
needs: [docker_preparation, fullstack_tests]
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Delete cache
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh extension install actions/gh-actions-cache
KEY="${{ github.run_id }}-e2e-preparation-cache"
gh actions-cache delete $KEY -R Ocelot-Social-Community/Ocelot-Social --confirm

View File

@ -1,7 +1,7 @@
name: ocelot.social webapp test CI
on: [push]
on: push
jobs:
files-changed:
@ -34,7 +34,7 @@ jobs:
run: |
scripts/translations/sort.sh
scripts/translations/missing-keys.sh
build_test_webapp:
name: Docker Build Test - Webapp
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.webapp == 'true'
@ -44,16 +44,16 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- name: webapp | Build 'test' image
- name: Webapp | Build 'test' image
run: |
docker build --target test -t "ocelotsocialnetwork/webapp:test" webapp/
docker save "ocelotsocialnetwork/webapp:test" > /tmp/webapp.tar
- name: Upload Artifact
uses: actions/upload-artifact@v3
- name: Cache docker image
uses: actions/cache/save@v3.3.1
with:
name: docker-webapp-test
path: /tmp/webapp.tar
key: ${{ github.run_id }}-webapp-cache
lint_webapp:
name: Lint Webapp
@ -78,20 +78,19 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- name: Download Docker Image (Webapp)
uses: actions/download-artifact@v3
- name: Restore webapp cache
uses: actions/cache/restore@v3.3.1
with:
name: docker-webapp-test
path: /tmp
path: /tmp/webapp.tar
key: ${{ github.run_id }}-webapp-cache
- name: Load Docker Image
run: docker load < /tmp/webapp.tar
- name: backend | copy env files webapp
run: cp webapp/.env.template webapp/.env
- name: backend | copy env files backend
run: cp backend/.env.template backend/.env
- name: Copy env files
run: |
cp webapp/.env.template webapp/.env
cp backend/.env.template backend/.env
- name: backend | docker-compose
run: docker-compose -f docker-compose.yml -f docker-compose.test.yml up --detach --no-deps webapp
@ -99,3 +98,18 @@ jobs:
- name: webapp | Unit tests incl. coverage check
run: docker-compose exec -T webapp yarn test
cleanup:
name: Cleanup
if: ${{ needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.webapp == 'true' }}
needs: [files-changed, unit_test_webapp]
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Delete cache
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh extension install actions/gh-actions-cache
KEY="${{ github.run_id }}-webapp-cache"
gh actions-cache delete $KEY -R Ocelot-Social-Community/Ocelot-Social --confirm

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,10 @@ export const createMessageMutation = () => {
CreateMessage(roomId: $roomId, content: $content) {
id
content
senderId
username
avatar
date
saved
distributed
seen
@ -17,12 +21,15 @@ export const createMessageMutation = () => {
export const messageQuery = () => {
return gql`
query ($roomId: ID!, $first: Int, $offset: Int) {
Message(roomId: $roomId, first: $first, offset: $offset, orderBy: createdAt_desc) {
Message(roomId: $roomId, first: $first, offset: $offset, orderBy: indexId_desc) {
_id
id
indexId
content
senderId
author {
id
}
username
avatar
date

View File

@ -6,18 +6,10 @@ export const createRoomMutation = () => {
CreateRoom(userId: $userId) {
id
roomId
}
}
`
}
export const roomQuery = () => {
return gql`
query {
Room {
id
roomId
roomName
lastMessageAt
unreadCount
#avatar
users {
_id
id
@ -30,3 +22,46 @@ export const roomQuery = () => {
}
`
}
export const roomQuery = () => {
return gql`
query Room($first: Int, $offset: Int, $id: ID) {
Room(first: $first, offset: $offset, id: $id, orderBy: lastMessageAt_desc) {
id
roomId
roomName
avatar
lastMessageAt
unreadCount
lastMessage {
_id
id
content
senderId
username
avatar
date
saved
distributed
seen
}
users {
_id
id
name
avatar {
url
}
}
}
}
`
}
export const unreadRoomsQuery = () => {
return gql`
query {
UnreadRooms
}
`
}

View File

@ -9,10 +9,9 @@ function walkRecursive(data, fields, fieldName, callback, _key?) {
if (!Array.isArray(fields)) {
throw new Error('please provide an fields array for the walkRecursive helper')
}
if (data && typeof data === 'string' && fields.includes(_key)) {
// well we found what we searched for, lets replace the value with our callback result
const key = _key.split('!')
if (key.length === 1 || key[1] !== fieldName) data = callback(data, key[0])
const fieldDef = fields.find((f) => f.field === _key)
if (data && typeof data === 'string' && fieldDef) {
if (!fieldDef.excludes?.includes(fieldName)) data = callback(data, _key)
} else if (data && Array.isArray(data)) {
// go into the rabbit hole and dig through that array
data.forEach((res, index) => {

View File

@ -0,0 +1,60 @@
import { isArray } from 'lodash'
const setRoomProps = (room) => {
if (room.users) {
room.users.forEach((user) => {
user._id = user.id
})
}
if (room.lastMessage) {
room.lastMessage._id = room.lastMessage.id
}
}
const setMessageProps = (message, context) => {
message._id = message.id
if (message.senderId !== context.user.id) {
message.distributed = true
}
}
const roomProperties = async (resolve, root, args, context, info) => {
const resolved = await resolve(root, args, context, info)
if (resolved) {
if (isArray(resolved)) {
resolved.forEach((room) => {
setRoomProps(room)
})
} else {
setRoomProps(resolved)
}
}
return resolved
}
const messageProperties = async (resolve, root, args, context, info) => {
const resolved = await resolve(root, args, context, info)
if (resolved) {
if (isArray(resolved)) {
resolved.forEach((message) => {
setMessageProps(message, context)
})
} else {
setMessageProps(resolved, context)
}
}
return resolved
}
export default {
Query: {
Room: roomProperties,
Message: messageProperties,
},
Mutation: {
CreateRoom: roomProperties,
},
Subscription: {
chatMessageAdded: messageProperties,
},
}

View File

@ -30,6 +30,7 @@ const standardSanitizeHtmlOptions = {
'strike',
'span',
'blockquote',
'usertag',
],
allowedAttributes: {
a: ['href', 'class', 'target', 'data-*', 'contenteditable'],

View File

@ -14,6 +14,7 @@ import login from './login/loginMiddleware'
import sentry from './sentryMiddleware'
import languages from './languages/languages'
import userInteractions from './userInteractions'
import chatMiddleware from './chatMiddleware'
export default (schema) => {
const middlewares = {
@ -31,6 +32,7 @@ export default (schema) => {
orderBy,
languages,
userInteractions,
chatMiddleware,
}
let order = [
@ -49,6 +51,7 @@ export default (schema) => {
'softDelete',
'includedFields',
'orderBy',
'chatMiddleware',
]
// add permisions middleware at the first position (unless we're seeding)

View File

@ -408,6 +408,7 @@ export default shield(
getInviteCode: isAuthenticated, // and inviteRegistration
Room: isAuthenticated,
Message: isAuthenticated,
UnreadRooms: isAuthenticated,
},
Mutation: {
'*': deny,

View File

@ -3,11 +3,11 @@ import { cleanHtml } from '../middleware/helpers/cleanHtml'
// exclamation mark separetes field names, that should not be sanitized
const fields = [
'content',
'contentExcerpt',
'reasonDescription',
'description!embed',
'descriptionExcerpt',
{ field: 'content', excludes: ['CreateMessage', 'Message'] },
{ field: 'contentExcerpt' },
{ field: 'reasonDescription' },
{ field: 'description', excludes: ['embed'] },
{ field: 'descriptionExcerpt' },
]
export default {

View File

@ -1,13 +1,15 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { getNeode, getDriver } from '../../db/neo4j'
import { createRoomMutation } from '../../graphql/rooms'
import { createRoomMutation, roomQuery } from '../../graphql/rooms'
import { createMessageMutation, messageQuery, markMessagesAsSeen } from '../../graphql/messages'
import createServer from '../../server'
import createServer, { pubsub } from '../../server'
const driver = getDriver()
const neode = getNeode()
const pubsubSpy = jest.spyOn(pubsub, 'publish')
let query
let mutate
let authenticatedUser
@ -22,6 +24,9 @@ beforeAll(async () => {
driver,
neode,
user: authenticatedUser,
cypherParams: {
currentUserId: authenticatedUser ? authenticatedUser.id : null,
},
}
},
})
@ -55,6 +60,10 @@ describe('Message', () => {
})
describe('create message', () => {
beforeEach(() => {
jest.clearAllMocks()
})
describe('unauthenticated', () => {
it('throws authorization error', async () => {
await expect(
@ -77,7 +86,7 @@ describe('Message', () => {
})
describe('room does not exist', () => {
it('returns null', async () => {
it('returns null and does not publish subscription', async () => {
await expect(
mutate({
mutation: createMessageMutation(),
@ -92,6 +101,7 @@ describe('Message', () => {
CreateMessage: null,
},
})
expect(pubsubSpy).not.toBeCalled()
})
})
@ -107,7 +117,7 @@ describe('Message', () => {
})
describe('user chats in room', () => {
it('returns the message', async () => {
it('returns the message and publishes subscriptions', async () => {
await expect(
mutate({
mutation: createMessageMutation(),
@ -122,12 +132,92 @@ describe('Message', () => {
CreateMessage: {
id: expect.any(String),
content: 'Some nice message to other chatting user',
senderId: 'chatting-user',
username: 'Chatting User',
avatar: expect.any(String),
date: expect.any(String),
saved: true,
distributed: false,
seen: false,
},
},
})
expect(pubsubSpy).toBeCalledWith('ROOM_COUNT_UPDATED', {
roomCountUpdated: '1',
userId: 'other-chatting-user',
})
expect(pubsubSpy).toBeCalledWith('CHAT_MESSAGE_ADDED', {
chatMessageAdded: expect.objectContaining({
id: expect.any(String),
content: 'Some nice message to other chatting user',
senderId: 'chatting-user',
username: 'Chatting User',
avatar: expect.any(String),
date: expect.any(String),
saved: true,
distributed: false,
seen: false,
}),
userId: 'other-chatting-user',
})
})
describe('room is updated as well', () => {
it('has last message set', async () => {
const result = await query({ query: roomQuery() })
await expect(result).toMatchObject({
errors: undefined,
data: {
Room: [
expect.objectContaining({
lastMessageAt: expect.any(String),
unreadCount: 0,
lastMessage: expect.objectContaining({
_id: result.data.Room[0].lastMessage.id,
id: expect.any(String),
content: 'Some nice message to other chatting user',
senderId: 'chatting-user',
username: 'Chatting User',
avatar: expect.any(String),
date: expect.any(String),
saved: true,
distributed: false,
seen: false,
}),
}),
],
},
})
})
})
describe('unread count for other user', () => {
it('has unread count = 1', async () => {
authenticatedUser = await otherChattingUser.toJson()
await expect(query({ query: roomQuery() })).resolves.toMatchObject({
errors: undefined,
data: {
Room: [
expect.objectContaining({
lastMessageAt: expect.any(String),
unreadCount: 1,
lastMessage: expect.objectContaining({
_id: expect.any(String),
id: expect.any(String),
content: 'Some nice message to other chatting user',
senderId: 'chatting-user',
username: 'Chatting User',
avatar: expect.any(String),
date: expect.any(String),
saved: true,
distributed: false,
seen: false,
}),
}),
],
},
})
})
})
})

View File

@ -1,7 +1,36 @@
import { neo4jgraphql } from 'neo4j-graphql-js'
import Resolver from './helpers/Resolver'
import { getUnreadRoomsCount } from './rooms'
import { pubsub, ROOM_COUNT_UPDATED, CHAT_MESSAGE_ADDED } from '../../server'
import { withFilter } from 'graphql-subscriptions'
const setMessagesAsDistributed = async (undistributedMessagesIds, session) => {
return session.writeTransaction(async (transaction) => {
const setDistributedCypher = `
MATCH (m:Message) WHERE m.id IN $undistributedMessagesIds
SET m.distributed = true
RETURN m { .* }
`
const setDistributedTxResponse = await transaction.run(setDistributedCypher, {
undistributedMessagesIds,
})
const messages = await setDistributedTxResponse.records.map((record) => record.get('m'))
return messages
})
}
export default {
Subscription: {
chatMessageAdded: {
subscribe: withFilter(
() => pubsub.asyncIterator(CHAT_MESSAGE_ADDED),
(payload, variables, context) => {
return payload.userId === context.user?.id
},
),
},
},
Query: {
Message: async (object, params, context, resolveInfo) => {
const { roomId } = params
@ -20,33 +49,15 @@ export default {
const undistributedMessagesIds = resolved
.filter((msg) => !msg.distributed && msg.senderId !== context.user.id)
.map((msg) => msg.id)
if (undistributedMessagesIds.length > 0) {
const session = context.driver.session()
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
const setDistributedCypher = `
MATCH (m:Message) WHERE m.id IN $undistributedMessagesIds
SET m.distributed = true
RETURN m { .* }
`
const setDistributedTxResponse = await transaction.run(setDistributedCypher, {
undistributedMessagesIds,
})
const messages = await setDistributedTxResponse.records.map((record) => record.get('m'))
return messages
})
try {
await writeTxResultPromise
} finally {
session.close()
const session = context.driver.session()
try {
if (undistributedMessagesIds.length > 0) {
await setMessagesAsDistributed(undistributedMessagesIds, session)
}
// send subscription to author to updated the messages
} finally {
session.close()
}
resolved.forEach((message) => {
message._id = message.id
if (message.senderId !== context.user.id) {
message.distributed = true
}
})
// send subscription to author to updated the messages
}
return resolved.reverse()
},
@ -61,31 +72,59 @@ export default {
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
const createMessageCypher = `
MATCH (currentUser:User { id: $currentUserId })-[:CHATS_IN]->(room:Room { id: $roomId })
OPTIONAL MATCH (currentUser)-[:AVATAR_IMAGE]->(image:Image)
OPTIONAL MATCH (m:Message)-[:INSIDE]->(room)
WITH MAX(m.indexId) as maxIndex, room, currentUser
OPTIONAL MATCH (room)<-[:CHATS_IN]-(recipientUser:User)
WHERE NOT recipientUser.id = $currentUserId
WITH MAX(m.indexId) as maxIndex, room, currentUser, image, recipientUser
CREATE (currentUser)-[:CREATED]->(message:Message {
createdAt: toString(datetime()),
id: apoc.create.uuid(),
indexId: CASE WHEN maxIndex IS NOT NULL THEN maxIndex + 1 ELSE 0 END,
content: $content,
content: LEFT($content,2000),
saved: true,
distributed: false,
seen: false
})-[:INSIDE]->(room)
RETURN message { .* }
SET room.lastMessageAt = toString(datetime())
RETURN message {
.*,
indexId: toString(message.indexId),
recipientId: recipientUser.id,
senderId: currentUser.id,
username: currentUser.name,
avatar: image.url,
date: message.createdAt
}
`
const createMessageTxResponse = await transaction.run(createMessageCypher, {
currentUserId,
roomId,
content,
})
const [message] = await createMessageTxResponse.records.map((record) =>
record.get('message'),
)
return message
})
try {
const message = await writeTxResultPromise
if (message) {
const roomCountUpdated = await getUnreadRoomsCount(message.recipientId, session)
// send subscriptions
void pubsub.publish(ROOM_COUNT_UPDATED, {
roomCountUpdated,
userId: message.recipientId,
})
void pubsub.publish(CHAT_MESSAGE_ADDED, {
chatMessageAdded: message,
userId: message.recipientId,
})
}
return message
} catch (error) {
throw new Error(error)

View File

@ -7,8 +7,8 @@ export default {
notificationAdded: {
subscribe: withFilter(
() => pubsub.asyncIterator(NOTIFICATION_ADDED),
(payload, variables) => {
return payload.notificationAdded.to.id === variables.userId
(payload, variables, context) => {
return payload.notificationAdded.to.id === context.user?.id
},
),
},

View File

@ -1,7 +1,8 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { getNeode, getDriver } from '../../db/neo4j'
import { createRoomMutation, roomQuery } from '../../graphql/rooms'
import { createRoomMutation, roomQuery, unreadRoomsQuery } from '../../graphql/rooms'
import { createMessageMutation } from '../../graphql/messages'
import createServer from '../../server'
const driver = getDriver()
@ -21,6 +22,9 @@ beforeAll(async () => {
driver,
neode,
user: authenticatedUser,
cypherParams: {
currentUserId: authenticatedUser ? authenticatedUser.id : null,
},
}
},
})
@ -34,6 +38,8 @@ afterAll(async () => {
})
describe('Room', () => {
let roomId: string
beforeAll(async () => {
;[chattingUser, otherChattingUser, notChattingUser] = await Promise.all([
Factory.build('user', {
@ -48,6 +54,14 @@ describe('Room', () => {
id: 'not-chatting-user',
name: 'Not Chatting User',
}),
Factory.build('user', {
id: 'second-chatting-user',
name: 'Second Chatting User',
}),
Factory.build('user', {
id: 'third-chatting-user',
name: 'Third Chatting User',
}),
])
})
@ -68,8 +82,6 @@ describe('Room', () => {
})
describe('authenticated', () => {
let roomId: string
beforeAll(async () => {
authenticatedUser = await chattingUser.toJson()
})
@ -122,6 +134,26 @@ describe('Room', () => {
CreateRoom: {
id: expect.any(String),
roomId: result.data.CreateRoom.id,
roomName: 'Other Chatting User',
unreadCount: 0,
users: expect.arrayContaining([
{
_id: 'chatting-user',
id: 'chatting-user',
name: 'Chatting User',
avatar: {
url: expect.any(String),
},
},
{
_id: 'other-chatting-user',
id: 'other-chatting-user',
name: 'Other Chatting User',
avatar: {
url: expect.any(String),
},
},
]),
},
},
})
@ -219,6 +251,7 @@ describe('Room', () => {
id: expect.any(String),
roomId: result.data.Room[0].id,
roomName: 'Chatting User',
unreadCount: 0,
users: expect.arrayContaining([
{
_id: 'chatting-user',
@ -260,4 +293,319 @@ describe('Room', () => {
})
})
})
describe('unread rooms query', () => {
describe('unauthenticated', () => {
it('throws authorization error', async () => {
authenticatedUser = null
await expect(
query({
query: unreadRoomsQuery(),
}),
).resolves.toMatchObject({
errors: [{ message: 'Not Authorized!' }],
})
})
})
describe('authenticated', () => {
let otherRoomId: string
beforeAll(async () => {
authenticatedUser = await chattingUser.toJson()
const result = await mutate({
mutation: createRoomMutation(),
variables: {
userId: 'not-chatting-user',
},
})
otherRoomId = result.data.CreateRoom.roomId
await mutate({
mutation: createMessageMutation(),
variables: {
roomId: otherRoomId,
content: 'Message to not chatting user',
},
})
await mutate({
mutation: createMessageMutation(),
variables: {
roomId,
content: '1st message to other chatting user',
},
})
await mutate({
mutation: createMessageMutation(),
variables: {
roomId,
content: '2nd message to other chatting user',
},
})
authenticatedUser = await otherChattingUser.toJson()
const result2 = await mutate({
mutation: createRoomMutation(),
variables: {
userId: 'not-chatting-user',
},
})
otherRoomId = result2.data.CreateRoom.roomId
await mutate({
mutation: createMessageMutation(),
variables: {
roomId: otherRoomId,
content: 'Other message to not chatting user',
},
})
})
describe('as chatting user', () => {
it('has 0 unread rooms', async () => {
authenticatedUser = await chattingUser.toJson()
await expect(
query({
query: unreadRoomsQuery(),
}),
).resolves.toMatchObject({
data: {
UnreadRooms: 0,
},
})
})
})
describe('as other chatting user', () => {
it('has 1 unread rooms', async () => {
authenticatedUser = await otherChattingUser.toJson()
await expect(
query({
query: unreadRoomsQuery(),
}),
).resolves.toMatchObject({
data: {
UnreadRooms: 1,
},
})
})
})
describe('as not chatting user', () => {
it('has 2 unread rooms', async () => {
authenticatedUser = await notChattingUser.toJson()
await expect(
query({
query: unreadRoomsQuery(),
}),
).resolves.toMatchObject({
data: {
UnreadRooms: 2,
},
})
})
})
})
})
describe('query several rooms', () => {
beforeAll(async () => {
authenticatedUser = await chattingUser.toJson()
await mutate({
mutation: createRoomMutation(),
variables: {
userId: 'second-chatting-user',
},
})
await mutate({
mutation: createRoomMutation(),
variables: {
userId: 'third-chatting-user',
},
})
})
it('returns the rooms paginated', async () => {
await expect(
query({ query: roomQuery(), variables: { first: 3, offset: 0 } }),
).resolves.toMatchObject({
errors: undefined,
data: {
Room: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
roomId: expect.any(String),
roomName: 'Third Chatting User',
lastMessageAt: null,
unreadCount: 0,
lastMessage: null,
users: expect.arrayContaining([
expect.objectContaining({
_id: 'chatting-user',
id: 'chatting-user',
name: 'Chatting User',
avatar: {
url: expect.any(String),
},
}),
expect.objectContaining({
_id: 'third-chatting-user',
id: 'third-chatting-user',
name: 'Third Chatting User',
avatar: {
url: expect.any(String),
},
}),
]),
}),
expect.objectContaining({
id: expect.any(String),
roomId: expect.any(String),
roomName: 'Second Chatting User',
lastMessageAt: null,
unreadCount: 0,
lastMessage: null,
users: expect.arrayContaining([
expect.objectContaining({
_id: 'chatting-user',
id: 'chatting-user',
name: 'Chatting User',
avatar: {
url: expect.any(String),
},
}),
expect.objectContaining({
_id: 'second-chatting-user',
id: 'second-chatting-user',
name: 'Second Chatting User',
avatar: {
url: expect.any(String),
},
}),
]),
}),
expect.objectContaining({
id: expect.any(String),
roomId: expect.any(String),
roomName: 'Other Chatting User',
lastMessageAt: expect.any(String),
unreadCount: 0,
lastMessage: {
_id: expect.any(String),
id: expect.any(String),
content: '2nd message to other chatting user',
senderId: 'chatting-user',
username: 'Chatting User',
avatar: expect.any(String),
date: expect.any(String),
saved: true,
distributed: false,
seen: false,
},
users: expect.arrayContaining([
expect.objectContaining({
_id: 'chatting-user',
id: 'chatting-user',
name: 'Chatting User',
avatar: {
url: expect.any(String),
},
}),
expect.objectContaining({
_id: 'other-chatting-user',
id: 'other-chatting-user',
name: 'Other Chatting User',
avatar: {
url: expect.any(String),
},
}),
]),
}),
]),
},
})
await expect(
query({ query: roomQuery(), variables: { first: 3, offset: 3 } }),
).resolves.toMatchObject({
errors: undefined,
data: {
Room: [
expect.objectContaining({
id: expect.any(String),
roomId: expect.any(String),
roomName: 'Not Chatting User',
users: expect.arrayContaining([
{
_id: 'chatting-user',
id: 'chatting-user',
name: 'Chatting User',
avatar: {
url: expect.any(String),
},
},
{
_id: 'not-chatting-user',
id: 'not-chatting-user',
name: 'Not Chatting User',
avatar: {
url: expect.any(String),
},
},
]),
}),
],
},
})
})
})
describe('query single room', () => {
let result: any = null
beforeAll(async () => {
authenticatedUser = await chattingUser.toJson()
result = await query({ query: roomQuery() })
})
describe('as chatter of room', () => {
it('returns the room', async () => {
expect(
await query({
query: roomQuery(),
variables: { first: 2, offset: 0, id: result.data.Room[0].id },
}),
).toMatchObject({
errors: undefined,
data: {
Room: [
{
id: expect.any(String),
roomId: expect.any(String),
roomName: result.data.Room[0].roomName,
users: expect.any(Array),
},
],
},
})
})
describe('as not chatter of room', () => {
beforeAll(async () => {
authenticatedUser = await notChattingUser.toJson()
})
it('returns no room', async () => {
authenticatedUser = await notChattingUser.toJson()
expect(
await query({
query: roomQuery(),
variables: { first: 2, offset: 0, id: result.data.Room[0].id },
}),
).toMatchObject({
errors: undefined,
data: {
Room: [],
},
})
})
})
})
})
})

View File

@ -1,29 +1,50 @@
import { neo4jgraphql } from 'neo4j-graphql-js'
import Resolver from './helpers/Resolver'
import { pubsub, ROOM_COUNT_UPDATED } from '../../server'
import { withFilter } from 'graphql-subscriptions'
export const getUnreadRoomsCount = async (userId, session) => {
return session.readTransaction(async (transaction) => {
const unreadRoomsCypher = `
MATCH (:User { id: $userId })-[:CHATS_IN]->(room:Room)<-[:INSIDE]-(message:Message)<-[:CREATED]-(sender:User)
WHERE NOT sender.id = $userId AND NOT message.seen
RETURN toString(COUNT(DISTINCT room)) AS count
`
const unreadRoomsTxResponse = await transaction.run(unreadRoomsCypher, { userId })
return unreadRoomsTxResponse.records.map((record) => record.get('count'))[0]
})
}
export default {
Subscription: {
roomCountUpdated: {
subscribe: withFilter(
() => pubsub.asyncIterator(ROOM_COUNT_UPDATED),
(payload, variables, context) => {
return payload.userId === context.user?.id
},
),
},
},
Query: {
Room: async (object, params, context, resolveInfo) => {
if (!params.filter) params.filter = {}
params.filter.users_some = {
id: context.user.id,
}
const resolved = await neo4jgraphql(object, params, context, resolveInfo)
if (resolved) {
resolved.forEach((room) => {
if (room.users) {
// buggy, you must query the username for this to function correctly
room.roomName = room.users.filter((user) => user.id !== context.user.id)[0].name
room.avatar =
room.users.filter((user) => user.id !== context.user.id)[0].avatar?.url ||
'default-avatar'
room.users.forEach((user) => {
user._id = user.id
})
}
})
return neo4jgraphql(object, params, context, resolveInfo)
},
UnreadRooms: async (object, params, context, resolveInfo) => {
const {
user: { id: currentUserId },
} = context
const session = context.driver.session()
try {
const count = await getUnreadRoomsCount(currentUserId, session)
return count
} finally {
session.close()
}
return resolved
},
},
Mutation: {
@ -44,7 +65,17 @@ export default {
ON CREATE SET
room.createdAt = toString(datetime()),
room.id = apoc.create.uuid()
RETURN room { .* }
WITH room, user, currentUser
OPTIONAL MATCH (room)<-[:INSIDE]-(message:Message)<-[:CREATED]-(sender:User)
WHERE NOT sender.id = $currentUserId AND NOT message.seen
WITH room, user, currentUser, message,
user.name AS roomName
RETURN room {
.*,
users: [properties(currentUser), properties(user)],
roomName: roomName,
unreadCount: toString(COUNT(DISTINCT message))
}
`
const createRommTxResponse = await transaction.run(createRoomCypher, {
userId,
@ -68,6 +99,7 @@ export default {
},
Room: {
...Resolver('Room', {
undefinedToNull: ['lastMessageAt'],
hasMany: {
users: '<-[:CHATS_IN]-(related:User)',
},

View File

@ -3,8 +3,7 @@
# }
enum _MessageOrdering {
createdAt_asc
createdAt_desc
indexId_desc
}
type Message {
@ -45,3 +44,7 @@ type Query {
orderBy: [_MessageOrdering]
): [Message]
}
type Subscription {
chatMessageAdded: Message
}

View File

@ -38,5 +38,5 @@ type Mutation {
}
type Subscription {
notificationAdded(userId: ID!): NOTIFIED
notificationAdded: NOTIFIED
}

View File

@ -5,6 +5,12 @@
# users_some: _UserFilter
# }
# TODO change this to last message date
enum _RoomOrdering {
lastMessageAt_desc
createdAt_desc
}
type Room {
id: ID!
createdAt: String
@ -13,8 +19,28 @@ type Room {
users: [User]! @relation(name: "CHATS_IN", direction: "IN")
roomId: String! @cypher(statement: "RETURN this.id")
roomName: String! ## @cypher(statement: "MATCH (this)<-[:CHATS_IN]-(user:User) WHERE NOT user.id = $cypherParams.currentUserId RETURN user[0].name")
avatar: String! ## @cypher match not own user in users array
roomName: String! @cypher(statement: "MATCH (this)<-[:CHATS_IN]-(user:User) WHERE NOT user.id = $cypherParams.currentUserId RETURN user.name")
avatar: String @cypher(statement: """
MATCH (this)<-[:CHATS_IN]-(user:User)
WHERE NOT user.id = $cypherParams.currentUserId
OPTIONAL MATCH (user)-[:AVATAR_IMAGE]->(image:Image)
RETURN image.url
""")
lastMessageAt: String
lastMessage: Message @cypher(statement: """
MATCH (this)<-[:INSIDE]-(message:Message)
WITH message ORDER BY message.indexId DESC LIMIT 1
RETURN message
""")
unreadCount: Int @cypher(statement: """
MATCH (this)<-[:INSIDE]-(message:Message)<-[:CREATED]-(user:User)
WHERE NOT user.id = $cypherParams.currentUserId
AND NOT message.seen
RETURN count(message)
""")
}
type Mutation {
@ -24,5 +50,13 @@ type Mutation {
}
type Query {
Room: [Room]
Room(
id: ID
orderBy: [_RoomOrdering]
): [Room]
UnreadRooms: Int
}
type Subscription {
roomCountUpdated: Int
}

View File

@ -14,6 +14,8 @@ import bodyParser from 'body-parser'
import { graphqlUploadExpress } from 'graphql-upload'
export const NOTIFICATION_ADDED = 'NOTIFICATION_ADDED'
export const CHAT_MESSAGE_ADDED = 'CHAT_MESSAGE_ADDED'
export const ROOM_COUNT_UPDATED = 'ROOM_COUNT_UPDATED'
const { REDIS_DOMAIN, REDIS_PORT, REDIS_PASSWORD } = CONFIG
let prodPubsub, devPubsub
const options = {

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>align-center</title>
<path d="M3 7h26v2h-26v-2zM7 11h18v2h-18v-2zM3 15h26v2h-26v-2zM7 19h18v2h-18v-2zM3 23h26v2h-26v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 274 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>align-justify</title>
<path d="M3 7h26v2h-26v-2zM3 11h26v2h-26v-2zM3 15h26v2h-26v-2zM3 19h26v2h-26v-2zM3 23h26v2h-26v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 275 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>align-left</title>
<path d="M3 7h26v2h-26v-2zM3 11h18v2h-18v-2zM3 15h26v2h-26v-2zM3 19h18v2h-18v-2zM3 23h26v2h-26v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 272 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>align-right</title>
<path d="M3 7h26v2h-26v-2zM11 11h18v2h-18v-2zM3 15h26v2h-26v-2zM11 19h18v2h-18v-2zM3 23h26v2h-26v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 275 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>angle-left</title>
<path d="M19.031 4.281l1.438 1.438-10.281 10.281 10.281 10.281-1.438 1.438-11-11-0.688-0.719 0.688-0.719z"></path>
</svg>

After

Width:  |  Height:  |  Size: 279 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>angle-right</title>
<path d="M12.969 4.281l11 11 0.688 0.719-0.688 0.719-11 11-1.438-1.438 10.281-10.281-10.281-10.281z"></path>
</svg>

After

Width:  |  Height:  |  Size: 274 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>archive</title>
<path d="M4 5h24v6h-1v16h-22v-16h-1v-6zM6 7v2h20v-2h-20zM7 11v14h18v-14h-18zM12.813 13c0.013-0.001 0.034-0.001 0.047-0.001s0.034 0.001 0.047 0.001c0.013-0.001 0.034-0.001 0.047-0.001s0.034 0.001 0.047 0.001l6.014-0c0.552 0 1 0.448 1 1s-0.448 1-1 1l-0.014-0h-6c-0.026 0.002-0.068 0.004-0.094 0.004-0.554 0-1.004-0.45-1.004-1.004 0-0.505 0.408-0.953 0.911-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 527 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>arrow-up</title>
<path d="M16 4.094l0.719 0.688 8.5 8.5-1.438 1.438-6.781-6.781v20.063h-2v-20.063l-6.781 6.781-1.438-1.438 8.5-8.5z"></path>
</svg>

After

Width:  |  Height:  |  Size: 286 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>bar-chart</title>
<path d="M21 4h8v24h-8v-24zM23 6v20h4v-20h-4zM3 10h8v18h-8v-18zM5 12v14h4v-14h-4zM12 16h8v12h-8v-12zM14 18v8h4v-8h-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 290 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>briefcase</title>
<path d="M16 3c1.864 0 3.399 1.275 3.844 3h9.156v20h-26v-20h9.156c0.445-1.725 1.98-3 3.844-3zM16 5c-0.81 0-1.428 0.385-1.75 1h3.5c-0.322-0.615-0.94-1-1.75-1zM5 8v9h22v-9h-22zM16 14c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM5 19v5h22v-5h-22z"></path>
</svg>

After

Width:  |  Height:  |  Size: 429 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>bug</title>
<path d="M10.719 3.281l2.313 2.313c0.923-0.39 1.922-0.594 2.969-0.594s2.046 0.203 2.969 0.594l2.313-2.313 1.438 1.438-1.938 1.938c1.462 1.119 2.61 2.755 3.344 4.656l2.438-1.219 0.875 1.813-2.75 1.375c0.183 0.876 0.313 1.782 0.313 2.719 0 0.34-0.006 0.666-0.031 1h3.031v2h-3.375c-0.242 1.043-0.561 2.039-1.031 2.938l3 2.25-1.188 1.625-2.938-2.188c-1.618 2.056-3.885 3.375-6.469 3.375s-4.851-1.319-6.469-3.375l-2.938 2.188-1.188-1.625 3-2.25c-0.47-0.898-0.789-1.894-1.031-2.938h-3.375v-2h3.031c-0.025-0.334-0.031-0.66-0.031-1 0-0.937 0.13-1.843 0.313-2.719l-2.75-1.375 0.875-1.813 2.438 1.219c0.734-1.901 1.882-3.538 3.344-4.656l-1.938-1.938zM16 7c-1.978 0-3.827 1.094-5.125 2.875 1.134 0.511 2.924 1.125 5.125 1.125s3.991-0.614 5.125-1.125c-1.298-1.781-3.147-2.875-5.125-2.875zM9.906 11.594c-0.569 1.292-0.906 2.788-0.906 4.406 0 4.629 2.698 8.282 6 8.906v-11.969c-2.17-0.162-3.941-0.801-5.094-1.344zM22.094 11.594c-1.153 0.542-2.924 1.182-5.094 1.344v11.969c3.302-0.625 6-4.278 6-8.906 0-1.618-0.337-3.115-0.906-4.406z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>calculator</title>
<path d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-16zM9 7h12v6h-12v-6zM11 9v2h8v-2h-8zM10 15h2v2h-2v-2zM14 15h2v2h-2v-2zM18 15h2v2h-2v-2zM10 19h2v2h-2v-2zM14 19h2v2h-2v-2zM18 19h2v2h-2v-2zM10 23h2v2h-2v-2zM14 23h2v2h-2v-2zM18 23h2v2h-2v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>camera</title>
<path d="M11.5 6h9l0.313 0.406 1.188 1.594h7v18h-26v-18h7l1.188-1.594zM12.5 8l-1.188 1.594-0.313 0.406h-6v14h22v-14h-6l-0.313-0.406-1.188-1.594h-7zM8 11c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM16 11c3.302 0 6 2.698 6 6s-2.698 6-6 6-6-2.698-6-6 2.698-6 6-6zM16 13c-2.221 0-4 1.779-4 4s1.779 4 4 4 4-1.779 4-4-1.779-4-4-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 508 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>cart-plus</title>
<path d="M4 7h2.219c0.918 0 1.716 0.61 1.938 1.5l2.625 10.5h12.469l2.406-9h2.094l-2.594 9.531c-0.238 0.87-1.004 1.469-1.906 1.469h-12.469c-0.918 0-1.714-0.61-1.938-1.5l-2.625-10.5h-2.219c-0.552 0-1-0.448-1-1s0.448-1 1-1zM22 21c1.645 0 3 1.355 3 3s-1.355 3-3 3-3-1.355-3-3 1.355-3 3-3zM13 21c1.645 0 3 1.355 3 3s-1.355 3-3 3-3-1.355-3-3 1.355-3 3-3zM16 7h2v3h3v2h-3v3h-2v-3h-3v-2h3v-3zM13 23c-0.564 0-1 0.436-1 1s0.436 1 1 1 1-0.436 1-1-0.436-1-1-1zM22 23c-0.564 0-1 0.436-1 1s0.436 1 1 1 1-0.436 1-1-0.436-1-1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 685 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>certificate</title>
<path d="M16 3c0.624 0 1.248 0.213 1.781 0.594l1.656 1.156 1.875 0.25h0.031c1.314 0.16 2.352 1.223 2.531 2.531 0.003 0.024 0.029 0.038 0.031 0.063h-0.031l0.375 1.875 1.156 1.656c0.762 1.067 0.73 2.476 0.031 3.594v0.031l-0.031 0.031-1.156 1.656-0.25 1.875 3.125 4.75 1.031 1.531h-4.781l-1.156 2.688-0.719 1.719-1.031-1.563-3.156-4.75c-0.818 0.379-1.779 0.349-2.625 0l-3.156 4.75-1.031 1.563-0.719-1.719-1.156-2.688h-4.781l1.031-1.531 3.219-4.906-0.313-1.719-1.188-1.656c-0.762-1.067-0.73-2.507-0.031-3.625v-0.031l0.031-0.031 1.156-1.5 0.25-1.938v-0.031l0.031-0.031c0.283-1.275 1.287-2.279 2.563-2.563l0.031-0.031h0.031l1.906-0.25 1.656-1.156c0.533-0.381 1.157-0.594 1.781-0.594zM16 5.031c-0.229 0-0.458 0.068-0.625 0.188l-2 1.438-0.25 0.031-2.094 0.281c-0.015 0.003-0.016 0.027-0.031 0.031-0.487 0.125-0.875 0.513-1 1-0.004 0.015-0.028 0.016-0.031 0.031l-0.281 2.094-0.031 0.281-0.156 0.188-1.25 1.625c-0.301 0.482-0.269 1.073-0.031 1.406l1.281 1.781 0.156 0.188 0.031 0.25 0.406 2.281v0.063c0.015 0.138 0.063 0.266 0.125 0.375 0.139 0.244 0.378 0.403 0.688 0.438h0.031l2.188 0.313 0.281 0.031 0.188 0.156 1.625 1.25c0.482 0.302 1.073 0.269 1.406 0.031l1.781-1.281 0.188-0.156 0.25-0.031 2.281-0.406h0.063c0.25-0.028 0.45-0.142 0.594-0.313v-0.031l0.063-0.031c0.084-0.122 0.138-0.273 0.156-0.438v-0.031l0.313-2.188 0.031-0.25 1.406-1.969c0.302-0.482 0.269-1.042 0.031-1.375l-1.281-1.781-0.156-0.188-0.031-0.219-0.406-2.219v-0.063c-0.050-0.447-0.365-0.763-0.813-0.813h-0.031l-2.188-0.313-0.25-0.031-0.219-0.156-1.781-1.281c-0.167-0.119-0.396-0.188-0.625-0.188zM22.906 20.25c-0.409 0.323-0.9 0.552-1.438 0.625-0.024 0.003-0.038 0.029-0.063 0.031v-0.031l-1.969 0.344-0.469 0.344 2.125 3.25 0.688-1.594 0.25-0.625h2.406zM9.094 20.281l-1.531 2.313h2.406l0.25 0.625 0.688 1.594 2.125-3.219-0.438-0.344-1.906-0.25c-0.010-0.001-0.021 0.001-0.031 0-0.595-0.072-1.135-0.338-1.563-0.719z"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>chain-broken</title>
<path d="M21.75 4c1.603 0 3.189 0.626 4.406 1.844 2.435 2.435 2.435 6.409 0 8.844l-1.469 1.469c-1.015 1.016-2.304 1.618-3.625 1.781l-0.25-2c0.901-0.111 1.745-0.494 2.438-1.188h0.031l1.469-1.469c1.671-1.671 1.671-4.36 0-6.031s-4.36-1.671-6.031 0l-1.469 1.469c-0.692 0.692-1.076 1.564-1.188 2.469l-2-0.25c0.162-1.319 0.765-2.609 1.781-3.625l1.469-1.469c1.218-1.218 2.834-1.844 4.438-1.844zM7.719 6.281l4 4-1.438 1.438-4-4zM10.938 14.063l0.25 2c-0.901 0.111-1.745 0.494-2.438 1.188h-0.031l-1.469 1.469c-1.671 1.671-1.671 4.36 0 6.031s4.36 1.671 6.031 0l1.469-1.469c0.692-0.692 1.076-1.564 1.188-2.469l2 0.25c-0.162 1.319-0.765 2.609-1.781 3.625l-1.469 1.469c-2.435 2.435-6.409 2.435-8.844 0s-2.435-6.409 0-8.844l1.469-1.469c1.015-1.016 2.304-1.618 3.625-1.781zM21.719 20.281l4 4-1.438 1.438-4-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 968 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>chain</title>
<path d="M21.75 4c1.671 0 3.225 0.661 4.406 1.844s1.844 2.735 1.844 4.406-0.662 3.255-1.844 4.438l-1.469 1.469c-1.181 1.183-2.766 1.844-4.438 1.844-0.793 0-1.565-0.153-2.281-0.438l1.625-1.625c0.215 0.038 0.432 0.063 0.656 0.063 1.138 0 2.226-0.445 3.031-1.25l1.469-1.469c1.66-1.66 1.66-4.372 0-6.031-0.804-0.805-1.863-1.25-3-1.25s-2.227 0.444-3.031 1.25l-1.469 1.469c-0.997 0.996-1.391 2.393-1.188 3.688l-1.625 1.625c-0.285-0.716-0.438-1.487-0.438-2.281 0-1.671 0.662-3.255 1.844-4.438l1.469-1.469c1.181-1.183 2.766-1.844 4.438-1.844zM19.281 11.281l1.438 1.438-8 8-1.438-1.438zM11.75 14c0.793 0 1.565 0.153 2.281 0.438l-1.625 1.625c-0.215-0.038-0.432-0.063-0.656-0.063-1.138 0-2.226 0.445-3.031 1.25l-1.469 1.469c-1.66 1.66-1.66 4.372 0 6.031 0.804 0.805 1.863 1.25 3 1.25s2.227-0.444 3.031-1.25l1.469-1.469c0.997-0.996 1.391-2.393 1.188-3.688l1.625-1.625c0.285 0.716 0.438 1.487 0.438 2.281 0 1.671-0.662 3.256-1.844 4.438l-1.469 1.469c-1.181 1.183-2.766 1.844-4.438 1.844s-3.225-0.661-4.406-1.844c-1.182-1.182-1.844-2.735-1.844-4.406s0.662-3.256 1.844-4.438l1.469-1.469c1.181-1.183 2.766-1.844 4.438-1.844z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>cloud-download</title>
<path d="M16 5c3.378 0 6.14 2.131 7.344 5.063 3.527 0.182 6.33 2.986 6.563 6.5 1.239 1.102 2.094 2.677 2.094 4.438 0 3.324-2.676 6-6 6h-20c-3.324 0-6-2.676-6-6 0-2.751 1.884-4.944 4.344-5.656 0.597-1.699 2.050-2.919 3.844-3.219 0.454-3.994 3.694-7.125 7.813-7.125zM16 7c-3.37 0-6 2.63-6 6v1h-1c-1.444 0-2.638 0.964-2.938 2.313l-0.125 0.656-0.656 0.125c-1.832 0.319-3.281 1.886-3.281 3.906 0 2.276 1.724 4 4 4h20c2.276 0 4-1.724 4-4 0-1.267-0.65-2.48-1.594-3.188l-0.406-0.313v-0.5c0-2.755-2.245-5-5-5h-1.031l-0.219-0.719c-0.779-2.51-2.988-4.281-5.75-4.281zM15 12h2v6.563l2.281-2.281 1.438 1.438-4 4-0.719 0.688-0.719-0.688-4-4 1.438-1.438 2.281 2.281v-6.563z"></path>
</svg>

After

Width:  |  Height:  |  Size: 835 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>cloud-upload</title>
<path d="M16 4c3.378 0 6.14 2.131 7.344 5.063 3.527 0.182 6.33 2.986 6.563 6.5 1.239 1.102 2.094 2.677 2.094 4.438 0 3.324-2.676 6-6 6h-20c-3.324 0-6-2.676-6-6 0-2.751 1.884-4.944 4.344-5.656 0.597-1.699 2.050-2.919 3.844-3.219 0.454-3.994 3.694-7.125 7.813-7.125zM16 6c-3.37 0-6 2.63-6 6v1h-1c-1.444 0-2.638 0.964-2.938 2.313l-0.125 0.656-0.656 0.125c-1.832 0.319-3.281 1.886-3.281 3.906 0 2.276 1.724 4 4 4h20c2.276 0 4-1.724 4-4 0-1.267-0.65-2.48-1.594-3.188l-0.406-0.313v-0.5c0-2.755-2.245-5-5-5h-1.031l-0.219-0.719c-0.779-2.51-2.988-4.281-5.75-4.281zM16 11.594l0.719 0.688 4 4-1.438 1.438-2.281-2.281v6.563h-2v-6.563l-2.281 2.281-1.438-1.438 4-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 827 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>cloud</title>
<path d="M16 5c2.451 0 4.563 1.302 5.813 3.219 0.392-0.089 0.755-0.219 1.188-0.219 3.302 0 6 2.698 6 6 1.73 1.055 3 2.835 3 5 0 3.302-2.698 6-6 6h-20c-3.302 0-6-2.698-6-6s2.698-6 6-6c0.211 0 0.394 0.040 0.594 0.063 0.531-1.191 1.439-2.083 2.656-2.563 0.698-3.129 3.419-5.5 6.75-5.5zM16 7c-2.522 0-4.581 1.836-4.938 4.25l-0.094 0.688-0.656 0.156c-1.11 0.265-2.002 1.136-2.25 2.25l-0.188 0.969-1-0.219c-0.298-0.067-0.584-0.094-0.875-0.094-2.22 0-4 1.78-4 4s1.78 4 4 4h20c2.22 0 4-1.78 4-4 0-1.662-1.009-3.078-2.438-3.688l-0.656-0.281 0.063-0.719c0.018-0.235 0.031-0.321 0.031-0.313 0-2.22-1.78-4-4-4-0.444 0-0.875 0.096-1.313 0.25l-0.844 0.281-0.375-0.781c-0.824-1.631-2.511-2.75-4.469-2.75z"></path>
</svg>

After

Width:  |  Height:  |  Size: 858 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>code</title>
<path d="M18 5h2l-6 22h-2zM7.938 6.406l1.625 1.188-6.313 8.406 6.313 8.406-1.625 1.188-6.75-9-0.438-0.594 0.438-0.594zM24.063 6.406l6.75 9 0.438 0.594-0.438 0.594-6.75 9-1.625-1.188 6.313-8.406-6.313-8.406z"></path>
</svg>

After

Width:  |  Height:  |  Size: 374 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>coffee</title>
<path d="M16-2h2v4h-2v-4zM20-1h2v3h-2v-3zM10 3h18v4h2c1.645 0 3 1.355 3 3v3c0 1.645-1.355 3-3 3h-2v5c0 1.645-1.355 3-3 3h-12c-1.645 0-3-1.355-3-3v-18zM12 5v16c0 0.555 0.445 1 1 1h12c0.555 0 1-0.445 1-1v-16h-14zM28 9v5h2c0.555 0 1-0.445 1-1v-3c0-0.555-0.445-1-1-1h-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 436 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>columns</title>
<path d="M5 5h22v22h-22v-22zM7 7v18h8v-18h-8zM17 7v18h8v-18h-8z"></path>
</svg>

After

Width:  |  Height:  |  Size: 234 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>compass</title>
<path d="M16 3c7.168 0 13 5.832 13 13s-5.832 13-13 13-13-5.832-13-13 5.832-13 13-13zM14.875 5.063c-5.226 0.529-9.341 4.695-9.813 9.938h0.938v2h-0.938c0.475 5.284 4.653 9.462 9.938 9.938v-0.938h2v0.938c5.284-0.475 9.462-4.653 9.938-9.938h-0.938v-2h0.938c-0.475-5.284-4.653-9.462-9.938-9.938v0.938h-2v-0.938c-0.041 0.004-0.084-0.004-0.125 0zM22.094 9.906l-3.688 8.5-8.5 3.688 3.688-8.5zM16 14.5c-0.8 0-1.5 0.7-1.5 1.5s0.7 1.5 1.5 1.5 1.5-0.7 1.5-1.5-0.7-1.5-1.5-1.5z"></path>
</svg>

After

Width:  |  Height:  |  Size: 635 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>credit-card</title>
<path d="M5 5h18c1.645 0 3 1.355 3 3v1h1c1.645 0 3 1.355 3 3v12c0 1.645-1.355 3-3 3h-18c-1.645 0-3-1.355-3-3v-1h-1c-1.645 0-3-1.355-3-3v-12c0-1.645 1.355-3 3-3zM5 7c-0.565 0-1 0.435-1 1v12c0 0.565 0.435 1 1 1h18c0.565 0 1-0.435 1-1v-9h-19v-2h19v-1c0-0.565-0.435-1-1-1h-18zM26 11v2h2v-1c0-0.565-0.435-1-1-1h-1zM26 15v5c0 1.645-1.355 3-3 3h-15v1c0 0.565 0.435 1 1 1h18c0.565 0 1-0.435 1-1v-9h-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 568 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>crop</title>
<path d="M8 4h2v16.563l10.563-10.563h-9.563v-2h11.563l3.719-3.719 1.438 1.438-3.719 3.719v11.563h-2v-9.563l-10.563 10.563h16.563v2h-4v4h-2v-4h-14v-14h-4v-2h4v-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 329 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>crosshairs</title>
<path d="M15 3h2v2.063c5.268 0.477 9.46 4.67 9.938 9.938h2.063v2h-2.063c-0.477 5.268-4.67 9.46-9.938 9.938v2.063h-2v-2.063c-5.268-0.477-9.46-4.67-9.938-9.938h-2.063v-2h2.063c0.477-5.268 4.67-9.46 9.938-9.938v-2.063zM15 7.031c-4.193 0.453-7.515 3.776-7.969 7.969h1.969v2h-1.969c0.453 4.193 3.776 7.515 7.969 7.969v-1.969h2v1.969c4.193-0.453 7.515-3.776 7.969-7.969h-1.969v-2h1.969c-0.453-4.193-3.776-7.515-7.969-7.969v1.969h-2v-1.969z"></path>
</svg>

After

Width:  |  Height:  |  Size: 607 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>cube</title>
<path d="M16 4.406l0.406 0.188 10 4.5 0.594 0.25v12.688l-0.5 0.281-10.5 5.844-0.5-0.281-10.5-5.844v-12.688l0.594-0.25 10-4.5zM16 6.594l-7.688 3.438 7.688 3.844 7.688-3.844zM7 11.625v9.219l8 4.438v-9.656zM25 11.625l-8 4v9.656l8-4.438v-9.219z"></path>
</svg>

After

Width:  |  Height:  |  Size: 408 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>cubes</title>
<path d="M16 4l0.375 0.156 6.625 2.656v6.719l5.406 2.344 0.594 0.281v8.063l-0.5 0.313-6 3.344-0.469 0.25-0.469-0.219-5.563-2.781-5.563 2.781-0.469 0.219-0.469-0.25-6-3.344-0.5-0.313v-8.063l0.594-0.281 5.406-2.344v-6.719l6.625-2.656zM16 6.188l-3.281 1.281 3.281 1.281 3.281-1.281zM11 8.938v4.625l4 1.781v-4.875zM21 8.938l-4 1.531v4.875l4-1.781v-4.625zM10 15.313l-3.625 1.563 3.625 1.813 3.625-1.781zM22 15.313l-2.5 1.094-1.125 0.5 3.625 1.781 3.625-1.813zM5 18.406v4.656l4 2.25v-4.906zM27 18.406l-4 2v4.906l4-2.25v-4.656zM15 18.469l-4 1.938v4.969l4-2v-4.906zM17 18.469v4.906l4 2v-4.969z"></path>
</svg>

After

Width:  |  Height:  |  Size: 754 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>cut</title>
<path d="M6 6c2.197 0 4 1.803 4 4 0 0.494-0.115 0.969-0.281 1.406l6.063 3.438 10.219-5.844h4l-20.281 11.594c0.166 0.438 0.281 0.913 0.281 1.406 0 2.197-1.803 4-4 4s-4-1.803-4-4 1.803-4 4-4c0.981 0 1.864 0.375 2.563 0.969l5.156-2.938-5.219-2.969c-0.691 0.568-1.543 0.938-2.5 0.938-2.197 0-4-1.803-4-4s1.803-4 4-4zM6 8c-0.977 0-1.784 0.677-1.969 1.594-0.026 0.131-0.031 0.267-0.031 0.406 0 1.116 0.884 2 2 2s2-0.884 2-2-0.884-2-2-2zM19.094 16.813l10.906 6.188h-4l-8.906-5.094zM6 20c-0.977 0-1.784 0.677-1.969 1.594-0.026 0.131-0.031 0.267-0.031 0.406 0 1.116 0.884 2 2 2s2-0.884 2-2-0.884-2-2-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 760 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>dashboard</title>
<path d="M16 4c6.616 0 12 5.384 12 12s-5.384 12-12 12-12-5.384-12-12 5.384-12 12-12zM16 6c-5.535 0-10 4.465-10 10s4.465 10 10 10 10-4.465 10-10-4.465-10-10-10zM16 7c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM10.344 9.344c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM20.938 9.656l1.438 1.406-4.438 4.438c0.041 0.16 0.063 0.327 0.063 0.5 0 1.105-0.895 2-2 2s-2-0.895-2-2 0.895-2 2-2c0.173 0 0.34 0.021 0.5 0.063zM8 15c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM24 15c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM10.344 20.656c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM21.656 20.656c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 882 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>diamond</title>
<path d="M9.531 6h12.938l5.313 6.375 0.5 0.594-0.5 0.656-11.781 15-0.781-1-11-14-0.5-0.656 0.5-0.594 5-6zM10.469 8l-3.344 4h4.313l2.688-4h-3.656zM17.875 8l2.688 4h4.313l-3.344-4h-3.656zM16 8.844l-2.125 3.156h4.25zM7.031 14l6.594 8.406-2.375-8.406h-4.219zM13.313 14l2.688 9.313 2.656-9.313h-5.344zM20.75 14l-2.375 8.375 6.594-8.375h-4.219z"></path>
</svg>

After

Width:  |  Height:  |  Size: 509 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>exchange</title>
<path d="M26.188-1.719l6.719 6.719-6.719 6.719-1.406-1.438 4.281-4.281h-21.063v-2h21.063l-4.281-4.281zM13.813 12.281l1.406 1.438-4.281 4.281h21.063v2h-21.063l4.281 4.281-1.406 1.438-6.719-6.719 0.719-0.719z"></path>
</svg>

After

Width:  |  Height:  |  Size: 378 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>exclamation-triangle</title>
<path d="M16 3.219l0.875 1.5 12 20.781 0.844 1.5h-27.438l0.844-1.5 12-20.781zM16 7.219l-10.25 17.781h20.5zM15 14h2v6h-2v-6zM15 21h2v2h-2v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 324 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>expand</title>
<path d="M14 5h13v13h-2v-9.563l-16.563 16.563h9.563v2h-13v-13h2v9.563l16.563-16.563h-9.563v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 264 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>external-link</title>
<path d="M18 5h9v9h-2v-5.563l-12.281 12.281-1.438-1.438 12.281-12.281h-5.563v-2zM5 9h13l-2 2h-9v14h14v-9l2-2v13h-18v-18z"></path>
</svg>

After

Width:  |  Height:  |  Size: 297 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>eyedropper</title>
<path d="M24.656 3.031c1.108 0 2.222 0.41 3.063 1.25 1.681 1.681 1.681 4.444 0 6.125l-2.813 2.781 1 1-1.406 1.406-1-1-9.5 9.5c-1.064 1.064-1.845 1.684-2.531 2.063s-1.277 0.493-1.688 0.563-0.636 0.113-1.063 0.344-1.040 0.696-2 1.656l-0.719 0.688-0.719-0.688-2-2-0.688-0.719 0.688-0.719c0.986-0.986 1.475-1.621 1.719-2.063s0.276-0.66 0.344-1.063 0.196-1.011 0.563-1.688 0.96-1.429 2-2.469l9.5-9.5-1-1 1.406-1.406 1 1 2.781-2.813c0.84-0.84 1.954-1.25 3.063-1.25zM24.656 5.031c-0.592 0-1.197 0.228-1.656 0.688l-2.781 2.781 3.281 3.281 2.781-2.781c0.919-0.919 0.919-2.362 0-3.281-0.46-0.46-1.033-0.688-1.625-0.688zM18.813 9.906l-9.5 9.5c-0.96 0.96-1.426 1.605-1.656 2.031s-0.274 0.621-0.344 1.031-0.184 1.033-0.563 1.719c-0.259 0.469-0.859 1.1-1.406 1.719l0.75 0.75c0.601-0.529 1.227-1.126 1.688-1.375 0.677-0.366 1.254-0.463 1.656-0.531s0.621-0.1 1.063-0.344 1.108-0.733 2.094-1.719l9.5-9.5z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>facebook</title>
<path d="M7 5h18c1.093 0 2 0.907 2 2v18c0 1.093-0.907 2-2 2h-18c-1.093 0-2-0.907-2-2v-18c0-1.093 0.907-2 2-2zM7 7v18h9.688v-6.75h-2.625v-3h2.625v-2.25c0-2.583 1.571-3.969 3.875-3.969 1.104 0 2.067 0.057 2.344 0.094v2.719h-1.625c-1.253 0-1.469 0.595-1.469 1.469v1.938h2.969l-0.375 3h-2.594v6.75h5.188v-18h-18z"></path>
</svg>

After

Width:  |  Height:  |  Size: 480 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>female</title>
<path d="M18.125 4h0.594l0.281 0.5 0.938 1.656c1.545 0.156 3.628 0.829 5.438 3.25 2.055 2.749 3.625 7.468 3.625 15.594v1h-9.656c-0.989 0.617-2.104 1-3.344 1s-2.355-0.375-3.344-1h-9.656v-1c0-9.134 1.977-14.423 4.969-17.438s6.852-3.563 10.156-3.563zM17.563 6.063c-2.914 0.059-5.867 0.568-8.188 2.906-2.366 2.384-4.16 6.895-4.313 15.031h5.406c-0.119-0.152-0.233-0.311-0.344-0.469-1.357-1.941-2.125-4.333-2.125-6.531 0-0.783 0.212-1.515 0.625-2.063s0.978-0.894 1.563-1.125c1.169-0.461 2.477-0.521 3.719-0.625s2.43-0.242 3.125-0.563 0.969-0.581 0.969-1.625h2c0 1.66-0.976 2.893-2.156 3.438s-2.492 0.644-3.75 0.75-2.45 0.221-3.156 0.5c-0.353 0.139-0.585 0.292-0.719 0.469s-0.219 0.4-0.219 0.844c0 1.711 0.643 3.824 1.75 5.406s2.587 2.594 4.25 2.594c1.665 0 3.144-1.014 4.25-2.594s1.75-3.684 1.75-5.406h2c0 2.207-0.767 4.624-2.125 6.563-0.102 0.146-0.203 0.297-0.313 0.438h5.375c-0.136-7.17-1.553-11.261-3.156-13.406-1.684-2.253-3.521-2.594-4.531-2.594h-0.594l-0.281-0.5zM13 17c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM19 17c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-archive-o</title>
<path d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-7v1h-2v-1h-7zM14 7h2v2h-2v-2zM14 10h2v2h-2v-2zM14 13h2v2.188c1.156 0.418 2 1.52 2 2.813 0 1.645-1.355 3-3 3s-3-1.355-3-3c0-1.292 0.844-2.394 2-2.813v-2.188zM15 17c-0.564 0-1 0.436-1 1s0.436 1 1 1 1-0.436 1-1-0.436-1-1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 442 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-audio-o</title>
<path d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-16zM15 9.719l5.25 1.313-0.5 1.938-2.75-0.688v6.719c0 1.645-1.355 3-3 3s-3-1.355-3-3 1.355-3 3-3c0.353 0 0.684 0.073 1 0.188v-6.469zM14 18c-0.564 0-1 0.436-1 1s0.436 1 1 1 1-0.436 1-1-0.436-1-1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 415 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-code-o</title>
<path d="M5 3h13.406l0.313 0.281 6 6 0.281 0.313v19.406h-20v-26zM7 5v22h16v-16h-6v-6h-10zM19 6.438v2.563h2.563zM15 13h2l-2 12h-2zM11.219 15.375l1.563 1.25-1.969 2.375 1.969 2.375-1.563 1.25-2.5-3-0.531-0.625 0.531-0.625zM18.781 15.375l2.5 3 0.531 0.625-0.531 0.625-2.5 3-1.563-1.25 1.969-2.375-1.969-2.375z"></path>
</svg>

After

Width:  |  Height:  |  Size: 481 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-excel-o</title>
<path d="M5 3h20v7h-2v-5h-16v5h-2v-7zM7 12h2l1 2 1-2h2l-2 4 2 4h-2l-1-2-1 2h-2l2-4zM14 12h2v6h2v2h-4v-8zM21.5 12c0.733 0 1.402 0.287 1.844 0.75s0.656 1.068 0.656 1.656h-2c0-0.112-0.035-0.22-0.094-0.281s-0.14-0.125-0.406-0.125c-0.217 0-0.5 0.283-0.5 0.5s0.283 0.5 0.5 0.5c1.383 0 2.5 1.117 2.5 2.5 0 1.3-1.081 2.5-2.5 2.5-0.732 0-1.413-0.232-1.875-0.719s-0.625-1.121-0.625-1.688h2c0 0.233 0.049 0.299 0.063 0.313s0.069 0.094 0.438 0.094c0.381 0 0.5-0.2 0.5-0.5 0-0.217-0.283-0.5-0.5-0.5-1.383 0-2.5-1.117-2.5-2.5s1.117-2.5 2.5-2.5zM5 22h2v5h16v-5h2v7h-20v-7z"></path>
</svg>

After

Width:  |  Height:  |  Size: 733 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-image-o</title>
<path d="M5 3h13.406l0.313 0.281 6 6 0.281 0.313v19.406h-20v-26zM7 5v22h16v-16h-6v-6h-10zM19 6.438v2.563h2.563zM20.094 14c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM13 15.594l0.719 0.688 2.281 2.281 1.281-1.281 0.719-0.688 0.719 0.688 3 3-1.438 1.438-2.281-2.281-1.281 1.281-0.719 0.688-0.719-0.688-2.281-2.281-3.281 3.281-1.438-1.438 4-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 530 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-movie-o</title>
<path d="M5 3h13.406l0.313 0.281 6 6 0.281 0.313v19.406h-20v-26zM7 5v22h16v-16h-6v-6h-10zM19 6.438v2.563h2.563zM12 13.219l1.5 0.938 5 3 1.438 0.844-1.438 0.844-5 3-1.5 0.938v-9.563zM14 16.75v2.5l2.094-1.25z"></path>
</svg>

After

Width:  |  Height:  |  Size: 382 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-pdf-o</title>
<path d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-16zM14.406 10.344h0.031c0.33 0.007 0.656 0.135 0.906 0.344 0.257 0.215 0.428 0.498 0.531 0.781 0.207 0.567 0.235 1.188 0.188 1.906-0.039 0.595-0.326 1.352-0.469 2.031 0.187 0.42 0.248 0.774 0.469 1.188 0.409 0.766 0.86 1.217 1.313 1.813 0.517-0.027 1.127-0.182 1.563-0.125 0.567 0.074 1.089 0.186 1.5 0.625 0.206 0.22 0.369 0.553 0.375 0.875s-0.098 0.607-0.25 0.875v0.031h-0.031c-0.345 0.586-0.969 0.976-1.594 0.938s-1.148-0.368-1.625-0.781c-0.236-0.205-0.429-0.616-0.656-0.875-0.529 0.060-0.906-0.001-1.469 0.125-0.537 0.12-0.902 0.332-1.406 0.5-0.334 0.672-0.599 1.509-0.969 2-0.4 0.531-0.818 0.984-1.406 1.188-0.294 0.102-0.645 0.097-0.969-0.031s-0.566-0.349-0.75-0.625c-0.372-0.529-0.404-1.263-0.125-1.781s0.747-0.887 1.281-1.219c0.496-0.308 1.245-0.45 1.875-0.688 0.276-0.598 0.576-0.984 0.813-1.656 0.275-0.783 0.321-1.455 0.5-2.219-0.35-0.837-0.787-1.712-0.938-2.438-0.128-0.62-0.169-1.181-0.031-1.719 0.069-0.269 0.184-0.535 0.438-0.75 0.246-0.208 0.601-0.317 0.906-0.313zM15.063 17.75c-0.060 0.184-0.061 0.348-0.125 0.531-0.055 0.157-0.13 0.252-0.188 0.406 0.048-0.011 0.077-0.052 0.125-0.063 0.285-0.064 0.499-0.012 0.781-0.063-0.193-0.295-0.413-0.496-0.594-0.813zM18.75 19.781c-0.064-0.008-0.211 0.037-0.281 0.031 0.243 0.17 0.495 0.308 0.563 0.313 0.080 0.005 0.096 0.018 0.219-0.188 0.012-0.021-0.007-0.015 0-0.031-0.045-0.019-0.163-0.081-0.5-0.125zM11.75 21.344c-0.031 0.019-0.095 0.044-0.125 0.063-0.409 0.254-0.646 0.522-0.719 0.656s-0.103 0.072 0 0.219h0.031c0.020 0.030-0.012 0.018 0 0.031 0.071-0.030 0.351-0.219 0.656-0.625 0.054-0.072 0.101-0.262 0.156-0.344z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-photo-o</title>
<path d="M5 3h13.406l0.313 0.281 6 6 0.281 0.313v19.406h-20v-26zM7 5v22h16v-16h-6v-6h-10zM19 6.438v2.563h2.563zM20.094 14c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM13 15.594l0.719 0.688 2.281 2.281 1.281-1.281 0.719-0.688 0.719 0.688 3 3-1.438 1.438-2.281-2.281-1.281 1.281-0.719 0.688-0.719-0.688-2.281-2.281-3.281 3.281-1.438-1.438 4-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 530 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-picture-o</title>
<path d="M5 3h13.406l0.313 0.281 6 6 0.281 0.313v19.406h-20v-26zM7 5v22h16v-16h-6v-6h-10zM19 6.438v2.563h2.563zM20.094 14c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM13 15.594l0.719 0.688 2.281 2.281 1.281-1.281 0.719-0.688 0.719 0.688 3 3-1.438 1.438-2.281-2.281-1.281 1.281-0.719 0.688-0.719-0.688-2.281-2.281-3.281 3.281-1.438-1.438 4-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 532 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-powerpoint-o</title>
<path d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-16zM12 11h4c2.21 0 4 1.79 4 4s-1.79 4-4 4c-0.74 0-1.406-0.244-2-0.594v3.594h-2v-7h2c0 1.19 0.81 2 2 2s2-0.81 2-2-0.81-2-2-2h-4v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 355 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-sound-o</title>
<path d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-16zM15 9.719l5.25 1.313-0.5 1.938-2.75-0.688v6.719c0 1.645-1.355 3-3 3s-3-1.355-3-3 1.355-3 3-3c0.353 0 0.684 0.073 1 0.188v-6.469zM14 18c-0.564 0-1 0.436-1 1s0.436 1 1 1 1-0.436 1-1-0.436-1-1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 415 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-text</title>
<path d="M5 3h13.406l0.313 0.281 6 6 0.281 0.313v19.406h-20v-26zM7 5v22h16v-16h-6v-6h-10zM19 6.438v2.563h2.563zM10 13h10v2h-10v-2zM10 17h10v2h-10v-2zM10 21h10v2h-10v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 341 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-video-o</title>
<path d="M5 3h13.406l0.313 0.281 6 6 0.281 0.313v19.406h-20v-26zM7 5v22h16v-16h-6v-6h-10zM19 6.438v2.563h2.563zM12 13.219l1.5 0.938 5 3 1.438 0.844-1.438 0.844-5 3-1.5 0.938v-9.563zM14 16.75v2.5l2.094-1.25z"></path>
</svg>

After

Width:  |  Height:  |  Size: 382 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-word-o</title>
<path d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-16zM17 12h4v2h-2v4.5c0 1.383-1.117 2.5-2.5 2.5-0.386 0-0.604-0.283-0.906-0.469-0.408 0.824-1.11 1.469-2.094 1.469-1.383 0-2.5-1.117-2.5-2.5v-4.5h-2v-2h4v6.5c0 0.217 0.283 0.5 0.5 0.5s0.5-0.283 0.5-0.5v-4.5h2v2s0.007 0.652 0.156 1.25c0.075 0.299 0.198 0.577 0.281 0.688s0.021 0.063 0.063 0.063c0.217 0 0.5-0.283 0.5-0.5v-6.5z"></path>
</svg>

After

Width:  |  Height:  |  Size: 543 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>file-zip-o</title>
<path d="M5 3h20v26h-20v-26zM7 5v22h16v-22h-7v1h-2v-1h-7zM14 7h2v2h-2v-2zM14 10h2v2h-2v-2zM14 13h2v2.188c1.156 0.418 2 1.52 2 2.813 0 1.645-1.355 3-3 3s-3-1.355-3-3c0-1.292 0.844-2.394 2-2.813v-2.188zM15 17c-0.564 0-1 0.436-1 1s0.436 1 1 1 1-0.436 1-1-0.436-1-1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 438 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>files-o</title>
<path d="M4 4h16v3h-2v-1h-12v16h5v2h-7v-20zM12 8h16v20h-16v-20zM14 10v16h12v-16h-12z"></path>
</svg>

After

Width:  |  Height:  |  Size: 255 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>film</title>
<path d="M4 4h24v24h-24v-24zM6 6v20h2v-1h2v1h12v-1h2v1h2v-20h-2v1h-2v-1h-12v1h-2v-1h-2zM8 9h2v2h-2v-2zM22 9h2v2h-2v-2zM8 13h2v2h-2v-2zM22 13h2v2h-2v-2zM8 17h2v2h-2v-2zM22 17h2v2h-2v-2zM8 21h2v2h-2v-2zM22 21h2v2h-2v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 385 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>fire</title>
<path d="M13.375 3h1.281l0.281 0.219s2.507 2.024 5 5.094 5.063 7.224 5.063 11.688c0 1.978-0.333 4.263-1.938 6.063-1.369 1.535-3.592 2.567-6.938 2.844-0.085 0.007-0.163 0.025-0.25 0.031-0.283 0.028-0.57 0.063-0.875 0.063-0.097 0-0.186-0.028-0.281-0.031-0.139 0.002-0.263 0.031-0.406 0.031-3.265 0-5.674-1.113-7.188-2.781s-2.125-3.807-2.125-5.813c0-4.244 1.984-7.63 3.969-10.344s3.919-4.935 4.219-6.281zM14.5 5.5c-0.868 1.866-2.366 3.645-3.906 5.75-1.892 2.586-3.594 5.534-3.594 9.156 0 1.595 0.508 3.237 1.625 4.469 0.238 0.262 0.514 0.493 0.813 0.719-0.078-0.193-0.164-0.391-0.219-0.594-0.619-2.311 0.099-5.073 1.969-7.594l0.938-1.281 0.75 1.406c0.511 0.955 1.047 1.345 1.344 1.438s0.424 0.063 0.719-0.281c0.589-0.689 1.141-3.002 0.094-6.406l-0.375-1.281h1.938l0.281 0.344c0.548 0.633 1.188 1.78 1.938 3.406s1.529 3.644 1.938 5.656c0.358 1.761 0.476 3.535-0.063 5.094 0.34-0.241 0.632-0.509 0.875-0.781 1.13-1.267 1.438-2.963 1.438-4.719 0-3.669-2.272-7.509-4.625-10.406-1.705-2.099-3.067-3.383-3.875-4.094zM17.563 17.219c-0.157 1.133-0.503 2.089-1.094 2.781-0.688 0.806-1.824 1.195-2.844 0.875-0.551-0.173-1.025-0.508-1.469-0.969-0.903 1.704-1.324 3.385-1 4.594 0.392 1.464 1.431 2.428 3.594 2.5 0.086 0.003 0.16 0 0.25 0 0.345-0.011 0.686-0.037 1-0.063 0.15-0.018 0.303-0.036 0.438-0.063 1.21-0.239 1.804-0.811 2.188-1.594 0.511-1.044 0.519-2.681 0.156-4.469-0.25-1.23-0.756-2.418-1.219-3.594z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>flask</title>
<path d="M17 0c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM14 3c0.552 0 1 0.448 1 1h7v2h-1v7.656l6.156 7.938c0.543 0.698 0.844 1.553 0.844 2.438 0 2.185-1.784 3.969-3.969 3.969h-16.063c-2.185 0-3.969-1.784-3.969-3.969 0-0.885 0.301-1.74 0.844-2.438l6.156-7.938v-7.656h-1v-2h3c0-0.552 0.448-1 1-1zM13 6v8.344l-2.844 3.656h11.688l-2.844-3.656v-8.344h-6zM17 10c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM8.594 20l-2.188 2.813c-0.269 0.346-0.406 0.779-0.406 1.219 0 1.105 0.864 1.969 1.969 1.969h16.063c1.105 0 1.969-0.864 1.969-1.969 0-0.439-0.137-0.873-0.406-1.219l-2.188-2.813h-14.813z"></path>
</svg>

After

Width:  |  Height:  |  Size: 782 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>floppy-o</title>
<path d="M5 5h17.406l0.313 0.281 4 4 0.281 0.313v17.406h-22v-22zM7 7v18h2v-9h14v9h2v-14.563l-3-3v5.563h-12v-6h-3zM12 7v4h8v-4h-2v2h-2v-2h-4zM11 18v7h10v-7h-10z"></path>
</svg>

After

Width:  |  Height:  |  Size: 331 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>folder-open</title>
<path d="M5 3h22v10.406l-0.281 0.313-1.719 1.719v12.563h-6v2.719l-1.219-0.25-12.781-2.656v-24.813zM14.125 5l2.875 0.719v9.344l1.719 1.719 0.281 0.313v8.906h4v-11.406l0.281-0.313 1.719-1.719v-7.563h-10.875zM7 5.281v20.906l10 2.094v-10.344l-1.719-1.719-0.281-0.313v-8.625z"></path>
</svg>

After

Width:  |  Height:  |  Size: 445 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>folder</title>
<path d="M6 3h22v10.406l-0.281 0.313-1.719 1.719v13.563h-20v-26zM8 5v22h16v-11.563l-1.719-1.719-0.281-0.313v-8.406h-14zM24 5v7.563l1 1 1-1v-7.563h-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 319 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>frown-o</title>
<path d="M16 4c6.616 0 12 5.384 12 12s-5.384 12-12 12-12-5.384-12-12 5.384-12 12-12zM16 6c-5.535 0-10 4.465-10 10s4.465 10 10 10 10-4.465 10-10-4.465-10-10-10zM11.5 12c0.828 0 1.5 0.672 1.5 1.5s-0.672 1.5-1.5 1.5-1.5-0.672-1.5-1.5 0.672-1.5 1.5-1.5zM20.5 12c0.828 0 1.5 0.672 1.5 1.5s-0.672 1.5-1.5 1.5-1.5-0.672-1.5-1.5 0.672-1.5 1.5-1.5zM16 18c2.667 0 5.020 1.335 6.469 3.344l-1.625 1.156c-1.092-1.514-2.835-2.5-4.844-2.5s-3.752 0.986-4.844 2.5l-1.625-1.156c1.448-2.008 3.801-3.344 6.469-3.344z"></path>
</svg>

After

Width:  |  Height:  |  Size: 667 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>gamepad</title>
<path d="M16 7c6.383 0 11.969 2.063 11.969 2.063l0.594 0.219 0.063 0.594 1.344 10.25c0.365 2.835-1.665 5.479-4.5 5.844-2.639 0.34-5.005-1.44-5.625-3.969h-7.688c-0.619 2.529-2.985 4.309-5.625 3.969-2.835-0.365-4.865-3.009-4.5-5.844l1.344-10.25 0.063-0.594 0.594-0.219s5.586-2.063 11.969-2.063zM16 9c-5.486 0-10.007 1.524-10.75 1.781l-1.219 9.625c-0.227 1.763 0.987 3.335 2.75 3.563s3.368-0.987 3.594-2.75l0.031-0.344 0.125-0.875h10.938l0.125 0.875 0.031 0.344c0.227 1.763 1.832 2.977 3.594 2.75 1.763-0.227 2.977-1.8 2.75-3.563l-1.219-9.625c-0.743-0.258-5.264-1.781-10.75-1.781zM9 12h2v2h2v2h-2v2h-2v-2h-2v-2h2v-2zM22 12c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM20 14c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM24 14c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1zM22 16c0.552 0 1 0.448 1 1s-0.448 1-1 1-1-0.448-1-1 0.448-1 1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>gear</title>
<path d="M13.188 3h5.625l0.156 0.813 0.594 2.969c0.951 0.374 1.814 0.903 2.594 1.531l2.906-1 0.781-0.25 0.406 0.719 2 3.438 0.406 0.719-0.594 0.531-2.25 1.969c0.084 0.513 0.188 1.022 0.188 1.563s-0.104 1.050-0.188 1.563l2.25 1.969 0.594 0.531-0.406 0.719-2 3.438-0.406 0.719-0.781-0.25-2.906-1c-0.78 0.628-1.642 1.157-2.594 1.531l-0.594 2.969-0.156 0.813h-5.625l-0.156-0.813-0.594-2.969c-0.951-0.374-1.814-0.903-2.594-1.531l-2.906 1-0.781 0.25-0.406-0.719-2-3.438-0.406-0.719 0.594-0.531 2.25-1.969c-0.084-0.513-0.188-1.022-0.188-1.563s0.104-1.050 0.188-1.563l-2.25-1.969-0.594-0.531 0.406-0.719 2-3.438 0.406-0.719 0.781 0.25 2.906 1c0.78-0.628 1.642-1.157 2.594-1.531l0.594-2.969zM14.813 5l-0.5 2.594-0.125 0.594-0.563 0.188c-1.138 0.355-2.169 0.955-3.031 1.75l-0.438 0.406-0.563-0.188-2.531-0.875-1.188 2.031 2 1.781 0.469 0.375-0.156 0.594c-0.128 0.57-0.188 1.153-0.188 1.75s0.060 1.18 0.188 1.75l0.156 0.594-0.469 0.375-2 1.781 1.188 2.031 2.531-0.875 0.563-0.188 0.438 0.406c0.863 0.795 1.894 1.395 3.031 1.75l0.563 0.188 0.125 0.594 0.5 2.594h2.375l0.5-2.594 0.125-0.594 0.563-0.188c1.138-0.355 2.169-0.955 3.031-1.75l0.438-0.406 0.563 0.188 2.531 0.875 1.188-2.031-2-1.781-0.438-0.375 0.125-0.594c0.128-0.572 0.188-1.153 0.188-1.75s-0.060-1.18-0.188-1.75l-0.156-0.594 0.469-0.375 2-1.781-1.188-2.031-2.531 0.875-0.563 0.188-0.438-0.406c-0.863-0.795-1.894-1.395-3.031-1.75l-0.563-0.188-0.125-0.594-0.5-2.594h-2.375zM16 11c2.75 0 5 2.25 5 5s-2.25 5-5 5-5-2.25-5-5 2.25-5 5-5zM16 13c-1.669 0-3 1.331-3 3s1.331 3 3 3 3-1.331 3-3-1.331-3-3-3z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>gears</title>
<path d="M21.5 2.5h2v1.406c0.828 0.146 1.586 0.474 2.25 0.938l0.938-0.938 1.406 1.406-0.938 0.938c0.464 0.664 0.792 1.421 0.938 2.25h1.406v2h-1.406c-0.147 0.837-0.466 1.613-0.938 2.281l0.969 1.031-1.469 1.375-0.938-1c-0.656 0.451-1.405 0.763-2.219 0.906v1.406h-2v-1.406c-0.828-0.146-1.586-0.474-2.25-0.938l-1.031 1.063-1.438-1.438 1.063-1.031c-0.464-0.664-0.792-1.421-0.938-2.25h-1.406v-2h1.406c0.143-0.814 0.456-1.563 0.906-2.219l-1-0.938 1.375-1.469 1.031 0.969c0.669-0.471 1.445-0.79 2.281-0.938v-1.406zM22.5 5.813c-2.055 0-3.688 1.632-3.688 3.688s1.632 3.688 3.688 3.688 3.688-1.632 3.688-3.688-1.632-3.688-3.688-3.688zM9.531 11.719l0.719 1.813c0.53-0.132 1.087-0.219 1.656-0.219 0.571 0 1.126 0.085 1.656 0.219l0.719-1.813 1.844 0.75-0.719 1.813c0.944 0.571 1.742 1.372 2.313 2.313l1.813-0.719 0.75 1.844-1.813 0.719c0.132 0.529 0.219 1.087 0.219 1.656s-0.086 1.126-0.219 1.656l1.813 0.719-0.75 1.844-1.813-0.719c-0.569 0.952-1.367 1.766-2.313 2.344l0.719 1.781-1.844 0.75-0.719-1.781c-0.529 0.134-1.087 0.219-1.656 0.219-0.573 0-1.123-0.084-1.656-0.219l-0.719 1.781-1.844-0.75 0.719-1.781c-0.961-0.577-1.765-1.384-2.344-2.344l-1.781 0.719-0.75-1.844 1.781-0.719c-0.134-0.53-0.219-1.087-0.219-1.656s0.085-1.128 0.219-1.656l-1.781-0.719 0.75-1.844 1.781 0.719c0.577-0.945 1.392-1.743 2.344-2.313l-0.719-1.813zM11.906 15.313c-2.663 0-4.813 2.118-4.813 4.781s2.15 4.813 4.813 4.813 4.781-2.15 4.781-4.813-2.118-4.781-4.781-4.781z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>gift</title>
<path d="M12 5c1.749 0 2.939 1.329 3.719 2.438 0.104 0.148 0.189 0.293 0.281 0.438 0.092-0.145 0.177-0.289 0.281-0.438 0.779-1.108 1.97-2.438 3.719-2.438 1.645 0 3 1.355 3 3 0 0.353-0.073 0.684-0.188 1h5.188v6h-1v13h-22v-13h-1v-6h5.188c-0.114-0.316-0.188-0.647-0.188-1 0-1.645 1.355-3 3-3zM12 7c-0.565 0-1 0.435-1 1s0.435 1 1 1h2.313c-0.121-0.206-0.097-0.22-0.25-0.438-0.627-0.892-1.436-1.563-2.063-1.563zM20 7c-0.626 0-1.436 0.671-2.063 1.563-0.153 0.217-0.129 0.232-0.25 0.438h2.313c0.565 0 1-0.435 1-1s-0.435-1-1-1zM6 11v2h9v-1h2v1h9v-2h-20zM7 15v11h8v-10h2v10h8v-11h-18z"></path>
</svg>

After

Width:  |  Height:  |  Size: 742 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>github</title>
<path d="M15.999 4c6.628 0 12.001 5.373 12.001 12.001 0 5.3-3.435 9.794-8.2 11.385-0.609 0.117-0.825-0.256-0.825-0.577 0-0.394 0.015-1.688 0.015-3.292 0-1.119-0.384-1.852-0.815-2.222 2.673-0.297 5.479-1.311 5.479-5.921 0-1.31-0.464-2.381-1.233-3.22 0.124-0.304 0.536-1.524-0.119-3.176 0 0-1.006-0.323-3.297 1.23-0.958-0.266-1.985-0.399-3.004-0.404-1.020 0.005-2.047 0.138-3.004 0.404-2.292-1.553-3.3-1.23-3.3-1.23-0.653 1.652-0.241 2.872-0.118 3.176-0.767 0.839-1.235 1.91-1.235 3.22 0 4.599 2.801 5.628 5.466 5.931-0.343 0.3-0.653 0.829-0.762 1.604-0.683 0.307-2.422 0.837-3.492-0.997 0 0-0.634-1.152-1.838-1.237 0 0-1.172-0.016-0.082 0.729 0 0 0.786 0.369 1.332 1.755 0 0 0.704 2.334 4.042 1.609 0.006 1.001 0.016 1.756 0.016 2.041 0 0.318-0.219 0.688-0.819 0.578-4.769-1.587-8.207-6.085-8.207-11.386 0-6.628 5.373-12.001 11.999-12.001z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1008 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>glass</title>
<path d="M8.25 5h15.5l0.25 0.594c0.585 1.326 1 3.076 1 5.406 0 4.616-3.516 8.431-8 8.938v6.063h5v2h-12v-2h5v-6.063c-4.484-0.506-8-4.322-8-8.938 0-2.325 0.413-4.077 1-5.406zM9.656 7c-0.362 1.001-0.656 2.235-0.656 4 0 3.877 3.123 7 7 7 3.535 0 6.421-2.603 6.906-6h-11.906v-2h11.938c-0.081-1.241-0.277-2.207-0.563-3h-12.719z"></path>
</svg>

After

Width:  |  Height:  |  Size: 490 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>group</title>
<path d="M8 7c3.302 0 6 2.698 6 6 0 1.984-0.975 3.75-2.469 4.844 1.459 0.725 2.68 1.862 3.469 3.281 0.789-1.42 2.010-2.557 3.469-3.281-1.494-1.094-2.469-2.86-2.469-4.844 0-3.302 2.698-6 6-6s6 2.698 6 6c0 1.984-0.975 3.75-2.469 4.844 2.638 1.31 4.469 4.020 4.469 7.156h-2c0-3.326-2.674-6-6-6s-6 2.674-6 6h-2c0-3.326-2.674-6-6-6s-6 2.674-6 6h-2c0-3.136 1.831-5.846 4.469-7.156-1.494-1.094-2.469-2.86-2.469-4.844 0-3.302 2.698-6 6-6zM8 9c-2.221 0-4 1.779-4 4s1.779 4 4 4 4-1.779 4-4-1.779-4-4-4zM22 9c-2.221 0-4 1.779-4 4s1.779 4 4 4 4-1.779 4-4-1.779-4-4-4z"></path>
</svg>

After

Width:  |  Height:  |  Size: 724 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>hand-o-down</title>
<path d="M10 2h16v16.844c0 1.409-0.998 2.642-2.375 2.938l-7.625 1.656v3.563c0 1.645-1.355 3-3 3s-3-1.355-3-3v-10.75l-0.75 0.188c-0.156 0.203-0.224 0.331-0.625 0.625-0.642 0.47-1.633 0.938-2.969 0.938-1.426 0.002-2.656-1.29-2.656-2.906v-0.406l0.281-0.313 6.719-6.781v-5.594zM12 4v3h12v-3h-12zM11.406 9l-6.313 6.406c0.082 0.421 0.255 0.594 0.563 0.594 0.903 0 1.459-0.273 1.813-0.531s0.438-0.438 0.438-0.438l0.188-0.344 0.406-0.125 2.25-0.594 1.25-0.313v13.344c0 0.565 0.435 1 1 1s1-0.435 1-1v-5.188l0.781-0.188 8.438-1.781c0.467-0.1 0.781-0.523 0.781-1v-9.844h-12.594z"></path>
</svg>

After

Width:  |  Height:  |  Size: 742 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>hand-o-left</title>
<path d="M16.906 3h0.406l0.313 0.281 6.781 6.719h5.594v16h-16.844c-1.409 0-2.642-0.998-2.938-2.375l-1.656-7.625h-3.563c-1.645 0-3-1.355-3-3s1.355-3 3-3h10.75l-0.188-0.75c-0.203-0.156-0.331-0.224-0.625-0.625-0.47-0.642-0.938-1.633-0.938-2.969-0.002-1.426 1.29-2.656 2.906-2.656zM16.594 5.094c-0.421 0.082-0.594 0.255-0.594 0.563 0 0.903 0.273 1.459 0.531 1.813s0.438 0.438 0.438 0.438l0.344 0.188 0.125 0.406 0.594 2.25 0.313 1.25h-13.344c-0.565 0-1 0.435-1 1s0.435 1 1 1h5.188l0.188 0.781 1.781 8.438c0.1 0.467 0.523 0.781 1 0.781h9.844v-12.594zM25 12v12h3v-12h-3z"></path>
</svg>

After

Width:  |  Height:  |  Size: 739 B

View File

@ -1,5 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>hand-pointer-o</title>
<path d="M13 2c1.645 0 3 1.355 3 3v4.188c0.316-0.114 0.647-0.188 1-0.188 0.767 0 1.467 0.3 2 0.781 0.533-0.481 1.233-0.781 2-0.781 1.395 0 2.578 0.982 2.906 2.281 0.368-0.163 0.762-0.281 1.188-0.281 1.645 0 3 1.355 3 3v7.813c0 4.533-3.654 8.188-8.188 8.188h-1.719c-1.935 0-3.651-0.675-5-1.688l-0.031-0.063-0.063-0.031-8.188-8.094v-0.031c-1.154-1.154-1.154-3.034 0-4.188s3.034-1.154 4.188 0l0.25 0.219 0.656 0.688v-11.813c0-1.645 1.355-3 3-3zM13 4c-0.555 0-1 0.445-1 1v16.625l-4.313-4.313c-0.446-0.446-0.929-0.446-1.375 0s-0.446 0.929 0 1.375l8.094 8c1.051 0.788 2.317 1.313 3.781 1.313h1.719c3.467 0 6.188-2.721 6.188-6.188v-7.813c0-0.555-0.445-1-1-1s-1 0.445-1 1v2h-2.094v-4c0-0.555-0.445-1-1-1s-1 0.445-1 1v4h-2v-4c0-0.555-0.445-1-1-1s-1 0.445-1 1v4h-2v-11c0-0.555-0.445-1-1-1z"></path>
<path d="M13 2c1.645 0 3 1.355 3 3v4.188c0.316-0.114 0.647-0.188 1-0.188 0.767 0 1.467 0.3 2 0.781 0.533-0.481 1.233-0.781 2-0.781 1.395 0 2.578 0.982 2.906 2.281 0.368-0.163 0.762-0.281 1.188-0.281 1.645 0 3 1.355 3 3v7.813c0 4.533-3.654 8.188-8.188 8.188h-1.719c-1.935 0-3.651-0.675-5-1.688l-0.031-0.063-0.063-0.031-8.188-8.094v-0.031c-1.154-1.154-1.154-3.034 0-4.188s3.034-1.154 4.188 0l0.25 0.219 0.656 0.688v-11.813c0-1.645 1.355-3 3-3zM13 4c-0.555 0-1 0.445-1 1v16.625l-4.313-4.313c-0.446-0.446-0.929-0.446-1.375 0s-0.446 0.929 0 1.375l8.094 8c1.051 0.788 2.317 1.313 3.781 1.313h1.719c3.467 0 6.188-2.721 6.188-6.188v-7.813c0-0.555-0.445-1-1-1s-1 0.445-1 1v2h-2.094v-4c0-0.555-0.445-1-1-1s-1 0.445-1 1v4h-2v-4c0-0.555-0.445-1-1-1s-1 0.445-1 1v4h-2v-11c0-0.555-0.445-1-1-1z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 958 B

After

Width:  |  Height:  |  Size: 957 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>hand-o-right</title>
<path d="M14.688 3h0.406c1.616 0 2.908 1.23 2.906 2.656 0 1.336-0.468 2.327-0.938 2.969-0.294 0.401-0.422 0.469-0.625 0.625l-0.188 0.75h10.75c1.645 0 3 1.355 3 3s-1.355 3-3 3h-3.563l-1.656 7.625c-0.296 1.377-1.529 2.375-2.938 2.375h-16.844v-16h5.594l6.781-6.719zM15.406 5.094l-6.406 6.313v12.594h9.844c0.477 0 0.9-0.314 1-0.781l1.781-8.438 0.188-0.781h5.188c0.565 0 1-0.435 1-1s-0.435-1-1-1h-13.344l0.313-1.25 0.594-2.25 0.125-0.406 0.344-0.188s0.179-0.084 0.438-0.438 0.531-0.91 0.531-1.813c0-0.308-0.172-0.481-0.594-0.563zM4 12v12h3v-12h-3z"></path>
</svg>

After

Width:  |  Height:  |  Size: 718 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>hand-stop-o</title>
<path d="M16 2c1.381 0 2.533 0.97 2.875 2.25 0.351-0.146 0.724-0.25 1.125-0.25 1.645 0 3 1.355 3 3v1.188c0.316-0.114 0.647-0.188 1-0.188 1.645 0 3 1.355 3 3v12c0 3.854-3.146 7-7 7h-4.625c-1.919 0-3.543-0.923-4.719-2.094l-6.781-6.781c-1.163-1.163-1.163-3.087 0-4.25s3.087-1.163 4.25 0l0.875 0.875v-10.75c0-1.645 1.355-3 3-3 0.401 0 0.774 0.104 1.125 0.25 0.342-1.28 1.494-2.25 2.875-2.25zM16 4c-0.565 0-1 0.435-1 1v10h-2v-8c0-0.565-0.435-1-1-1s-1 0.435-1 1v15.594l-1.719-1.719-2.563-2.594c-0.399-0.399-1.039-0.399-1.438 0s-0.399 1.039 0 1.438l6.813 6.75c0.913 0.909 2.009 1.531 3.281 1.531h4.625c2.774 0 5-2.226 5-5v-12c0-0.565-0.435-1-1-1s-1 0.435-1 1v4h-2v-8c0-0.565-0.435-1-1-1s-1 0.435-1 1v8h-2v-10c0-0.565-0.435-1-1-1z"></path>
</svg>

After

Width:  |  Height:  |  Size: 897 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>hand-o-up</title>
<path d="M13 2c1.645 0 3 1.355 3 3v3.563l7.625 1.656c1.377 0.296 2.375 1.529 2.375 2.938v16.844h-16v-5.594l-6.719-6.781-0.281-0.313v-0.406c0-1.616 1.23-2.908 2.656-2.906 1.336 0 2.327 0.468 2.969 0.938 0.401 0.294 0.469 0.422 0.625 0.625l0.75 0.188v-10.75c0-1.645 1.355-3 3-3zM13 4c-0.565 0-1 0.435-1 1v13.344l-1.25-0.313-2.25-0.594-0.406-0.125-0.188-0.344s-0.084-0.179-0.438-0.438-0.91-0.531-1.813-0.531c-0.308-0-0.481 0.172-0.563 0.594l6.313 6.406h12.594v-9.844c0-0.477-0.314-0.9-0.781-1l-8.438-1.781-0.781-0.188v-5.188c0-0.565-0.435-1-1-1zM12 25v3h12v-3h-12z"></path>
</svg>

After

Width:  |  Height:  |  Size: 734 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>headphones</title>
<path d="M16 5c6.063 0 11 4.937 11 11v8c0 1.645-1.355 3-3 3h-3v-9h4v-2c0-4.983-4.017-9-9-9s-9 4.017-9 9v2h4v9h-3c-1.645 0-3-1.355-3-3v-8c0-6.063 4.937-11 11-11zM7 20v4c0 0.565 0.435 1 1 1h1v-5h-2zM23 20v5h1c0.565 0 1-0.435 1-1v-4h-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>heart</title>
<path d="M22.5 5c4.136 0 7.5 3.364 7.5 7.5 0 2.59-2.365 4.947-2.466 5.047l-11.534 11.534-11.54-11.54c-0.095-0.094-2.46-2.451-2.46-5.041 0-4.136 3.364-7.5 7.5-7.5 2.892 0 5.327 1.804 6.5 2.854 1.173-1.050 3.608-2.854 6.5-2.854z"></path>
</svg>

After

Width:  |  Height:  |  Size: 395 B

Some files were not shown because too many files have changed in this diff Show More