Merge remote-tracking branch 'origin/main' into neue/post-avi
* origin/main: Remove image resizer (#5464) Remove `react-native-fs` (#5463) Revamp image editor (#5462) Revamp edit image alt text dialog (#5461) MobX removal take 2 (#5381) Edit self hosting copy (#5469) Automatically optimise SVG assets (#5467) [Share Extension] Update to support video (#5385) Revert change in FAB animation (#5465) Improvements to NSE (#4992) Don't use flex on inputs (#5458) Fix web splash (#5456) invert the fab animation, play a haptic (#4309) add sideborders to <ProfileHeaderLoading> (#4995) [Video] Flush low quality segments once focused (#5430)
@@ -1,26 +1,30 @@
|
|||||||
import ImageResizer from '@bam.tech/react-native-image-resizer'
|
import {deleteAsync} from 'expo-file-system'
|
||||||
|
import {manipulateAsync, SaveFormat} from 'expo-image-manipulator'
|
||||||
import RNFetchBlob from 'rn-fetch-blob'
|
import RNFetchBlob from 'rn-fetch-blob'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
downloadAndResize,
|
downloadAndResize,
|
||||||
DownloadAndResizeOpts,
|
DownloadAndResizeOpts,
|
||||||
|
getResizedDimensions,
|
||||||
} from '../../src/lib/media/manip'
|
} from '../../src/lib/media/manip'
|
||||||
|
|
||||||
|
const mockResizedImage = {
|
||||||
|
path: 'file://resized-image.jpg',
|
||||||
|
size: 100,
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
mime: 'image/jpeg',
|
||||||
|
}
|
||||||
|
|
||||||
describe('downloadAndResize', () => {
|
describe('downloadAndResize', () => {
|
||||||
const errorSpy = jest.spyOn(global.console, 'error')
|
const errorSpy = jest.spyOn(global.console, 'error')
|
||||||
|
|
||||||
const mockResizedImage = {
|
|
||||||
path: jest.fn().mockReturnValue('file://resized-image.jpg'),
|
|
||||||
size: 100,
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
mime: 'image/jpeg',
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const mockedCreateResizedImage =
|
const mockedCreateResizedImage = manipulateAsync as jest.Mock
|
||||||
ImageResizer.createResizedImage as jest.Mock
|
mockedCreateResizedImage.mockResolvedValue({
|
||||||
mockedCreateResizedImage.mockResolvedValue(mockResizedImage)
|
uri: 'file://resized-image.jpg',
|
||||||
|
...mockResizedImage,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -54,17 +58,17 @@ describe('downloadAndResize', () => {
|
|||||||
'GET',
|
'GET',
|
||||||
'https://example.com/image.jpg',
|
'https://example.com/image.jpg',
|
||||||
)
|
)
|
||||||
expect(ImageResizer.createResizedImage).toHaveBeenCalledWith(
|
|
||||||
'file://downloaded-image.jpg',
|
// First time it gets called is to get dimensions
|
||||||
100,
|
expect(manipulateAsync).toHaveBeenCalledWith(expect.any(String), [], {})
|
||||||
100,
|
expect(manipulateAsync).toHaveBeenCalledWith(
|
||||||
'JPEG',
|
expect.any(String),
|
||||||
100,
|
[{resize: {height: opts.height, width: opts.width}}],
|
||||||
undefined,
|
{format: SaveFormat.JPEG, compress: 1.0},
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
{mode: 'cover'},
|
|
||||||
)
|
)
|
||||||
|
expect(deleteAsync).toHaveBeenCalledWith(expect.any(String), {
|
||||||
|
idempotent: true,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return undefined for invalid URI', async () => {
|
it('should return undefined for invalid URI', async () => {
|
||||||
@@ -82,46 +86,6 @@ describe('downloadAndResize', () => {
|
|||||||
expect(result).toBeUndefined()
|
expect(result).toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return undefined for unsupported file type', async () => {
|
|
||||||
const mockedFetch = RNFetchBlob.fetch as jest.Mock
|
|
||||||
mockedFetch.mockResolvedValueOnce({
|
|
||||||
path: jest.fn().mockReturnValue('file://downloaded-image'),
|
|
||||||
info: jest.fn().mockReturnValue({status: 200}),
|
|
||||||
flush: jest.fn(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const opts: DownloadAndResizeOpts = {
|
|
||||||
uri: 'https://example.com/image',
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
maxSize: 500000,
|
|
||||||
mode: 'cover',
|
|
||||||
timeout: 10000,
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await downloadAndResize(opts)
|
|
||||||
expect(result).toEqual(mockResizedImage)
|
|
||||||
expect(RNFetchBlob.config).toHaveBeenCalledWith({
|
|
||||||
fileCache: true,
|
|
||||||
appendExt: 'jpeg',
|
|
||||||
})
|
|
||||||
expect(RNFetchBlob.fetch).toHaveBeenCalledWith(
|
|
||||||
'GET',
|
|
||||||
'https://example.com/image',
|
|
||||||
)
|
|
||||||
expect(ImageResizer.createResizedImage).toHaveBeenCalledWith(
|
|
||||||
'file://downloaded-image',
|
|
||||||
100,
|
|
||||||
100,
|
|
||||||
'JPEG',
|
|
||||||
100,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
{mode: 'cover'},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should return undefined for non-200 response', async () => {
|
it('should return undefined for non-200 response', async () => {
|
||||||
const mockedFetch = RNFetchBlob.fetch as jest.Mock
|
const mockedFetch = RNFetchBlob.fetch as jest.Mock
|
||||||
mockedFetch.mockResolvedValueOnce({
|
mockedFetch.mockResolvedValueOnce({
|
||||||
@@ -143,4 +107,44 @@ describe('downloadAndResize', () => {
|
|||||||
expect(errorSpy).not.toHaveBeenCalled()
|
expect(errorSpy).not.toHaveBeenCalled()
|
||||||
expect(result).toBeUndefined()
|
expect(result).toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should not downsize whenever dimensions are below the max dimensions', () => {
|
||||||
|
const initialDimensionsOne = {
|
||||||
|
width: 1200,
|
||||||
|
height: 1000,
|
||||||
|
}
|
||||||
|
const resizedDimensionsOne = getResizedDimensions(initialDimensionsOne)
|
||||||
|
|
||||||
|
const initialDimensionsTwo = {
|
||||||
|
width: 1000,
|
||||||
|
height: 1200,
|
||||||
|
}
|
||||||
|
const resizedDimensionsTwo = getResizedDimensions(initialDimensionsTwo)
|
||||||
|
|
||||||
|
expect(resizedDimensionsOne).toEqual(initialDimensionsOne)
|
||||||
|
expect(resizedDimensionsTwo).toEqual(initialDimensionsTwo)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should resize dimensions and maintain aspect ratio if they are above the max dimensons', () => {
|
||||||
|
const initialDimensionsOne = {
|
||||||
|
width: 3000,
|
||||||
|
height: 1500,
|
||||||
|
}
|
||||||
|
const resizedDimensionsOne = getResizedDimensions(initialDimensionsOne)
|
||||||
|
|
||||||
|
const initialDimensionsTwo = {
|
||||||
|
width: 2000,
|
||||||
|
height: 4000,
|
||||||
|
}
|
||||||
|
const resizedDimensionsTwo = getResizedDimensions(initialDimensionsTwo)
|
||||||
|
|
||||||
|
expect(resizedDimensionsOne).toEqual({
|
||||||
|
width: 2000,
|
||||||
|
height: 1000,
|
||||||
|
})
|
||||||
|
expect(resizedDimensionsTwo).toEqual({
|
||||||
|
width: 1000,
|
||||||
|
height: 2000,
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M5 11a7 7 0 0 1 14 0c0 2.625-1.547 5.138-3.354 7.066a17.23 17.23 0 0 1-2.55 2.242 8.246 8.246 0 0 1-.924.577 2.904 2.904 0 0 1-.172.083 2.904 2.904 0 0 1-.172-.083 8.246 8.246 0 0 1-.923-.577 17.227 17.227 0 0 1-2.55-2.242C6.547 16.138 5 13.625 5 11Zm6.882 10.012Zm.232-.001h-.003a.047.047 0 0 0 .007.001l-.004-.001ZM12 2a9 9 0 0 0-9 9c0 3.375 1.953 6.362 3.895 8.434a19.216 19.216 0 0 0 2.856 2.508c.425.3.82.545 1.159.72.168.087.337.164.498.222.14.05.356.116.592.116s.451-.066.592-.116c.16-.058.33-.135.498-.222.339-.175.734-.42 1.159-.72.85-.6 1.87-1.457 2.856-2.508C19.047 17.362 21 14.375 21 11a9 9 0 0 0-9-9ZM7.38 9.927c2.774-.094 3.459 1.31 3.591 3.19a.89.89 0 0 1-.855.956c-2.774.094-3.458-1.31-3.59-3.19a.89.89 0 0 1 .854-.956Zm9.236 0c-2.774-.094-3.458 1.31-3.59 3.19a.89.89 0 0 0 .854.956c2.774.094 3.459-1.31 3.591-3.19a.89.89 0 0 0-.855-.956Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M5 11a7 7 0 0 1 14 0c0 2.625-1.547 5.138-3.354 7.066a17 17 0 0 1-2.55 2.242 8 8 0 0 1-.924.577 3 3 0 0 1-.172.083 3 3 0 0 1-.172-.083 8 8 0 0 1-.923-.577 17 17 0 0 1-2.55-2.242C6.547 16.138 5 13.625 5 11Zm6.882 10.012Zm.232-.001h-.003l.007.001-.004-.001ZM12 2a9 9 0 0 0-9 9c0 3.375 1.953 6.362 3.895 8.434a19 19 0 0 0 2.856 2.508c.425.3.82.545 1.159.72.168.087.337.164.498.222.14.05.356.116.592.116s.451-.066.592-.116c.16-.058.33-.135.498-.222.339-.175.734-.42 1.159-.72.85-.6 1.87-1.457 2.856-2.508C19.047 17.362 21 14.375 21 11a9 9 0 0 0-9-9ZM7.38 9.927c2.774-.094 3.459 1.31 3.591 3.19a.89.89 0 0 1-.855.956c-2.774.094-3.458-1.31-3.59-3.19a.89.89 0 0 1 .854-.956Zm9.236 0c-2.774-.094-3.458 1.31-3.59 3.19a.89.89 0 0 0 .854.956c2.774.094 3.459-1.31 3.591-3.19a.89.89 0 0 0-.855-.956Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 997 B After Width: | Height: | Size: 928 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M8.148 2.034a1 1 0 0 1 1.35-.419c1.054.556 1.873 1.266 2.46 2.174.369.57.63 1.197.807 1.873 1.143-.349 2.194-.46 3.15-.342a5.122 5.122 0 0 1 3.134 1.556c1.564 1.63 2.086 4.183 1.922 6.58-.166 2.414-1.043 4.938-2.607 6.619-.792.851-1.78 1.505-2.95 1.782-1.063.251-2.213.176-3.415-.262-1.202.438-2.351.513-3.414.262-1.17-.277-2.158-.93-2.95-1.782-1.563-1.682-2.44-4.205-2.606-6.62-.164-2.396.358-4.949 1.921-6.579A5.121 5.121 0 0 1 8.085 5.32c.777-.095 1.617-.04 2.518.172a4.011 4.011 0 0 0-.325-.618c-.372-.576-.912-1.068-1.712-1.49a1 1 0 0 1-.418-1.35Zm.897 17.877c.71.167 1.557.117 2.562-.31a1 1 0 0 1 .784 0c1.005.428 1.853.477 2.563.31.715-.17 1.37-.579 1.946-1.198 1.171-1.26 1.932-3.303 2.076-5.394.144-2.109-.353-3.998-1.37-5.059a3.124 3.124 0 0 0-1.936-.955c-.83-.102-1.912.043-3.282.621a1 1 0 0 1-.778 0c-1.37-.578-2.45-.723-3.281-.62-.815.1-1.445.443-1.935.954-1.017 1.06-1.514 2.95-1.37 5.059.144 2.09.905 4.135 2.076 5.394.575.62 1.23 1.029 1.945 1.198Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M8.148 2.034a1 1 0 0 1 1.35-.419c1.054.556 1.873 1.266 2.46 2.174.369.57.63 1.197.807 1.873 1.143-.349 2.194-.46 3.15-.342a5.12 5.12 0 0 1 3.134 1.556c1.564 1.63 2.086 4.183 1.922 6.58-.166 2.414-1.043 4.938-2.607 6.619-.792.851-1.78 1.505-2.95 1.782-1.063.251-2.213.176-3.415-.262-1.202.438-2.351.513-3.414.262-1.17-.277-2.158-.93-2.95-1.782-1.563-1.682-2.44-4.205-2.606-6.62-.164-2.396.358-4.949 1.921-6.579A5.12 5.12 0 0 1 8.085 5.32q1.166-.144 2.518.172a4 4 0 0 0-.325-.618c-.372-.576-.912-1.068-1.712-1.49a1 1 0 0 1-.418-1.35Zm.897 17.877c.71.167 1.557.117 2.562-.31a1 1 0 0 1 .784 0c1.005.428 1.853.477 2.563.31.715-.17 1.37-.579 1.946-1.198 1.171-1.26 1.932-3.303 2.076-5.394.144-2.109-.353-3.998-1.37-5.059a3.12 3.12 0 0 0-1.936-.955c-.83-.102-1.912.043-3.282.621a1 1 0 0 1-.778 0c-1.37-.578-2.45-.723-3.281-.62-.815.1-1.445.443-1.935.954-1.017 1.06-1.514 2.95-1.37 5.059.144 2.09.905 4.135 2.076 5.394.575.62 1.23 1.029 1.945 1.198Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M20.957 3.043a1 1 0 0 1 0 1.414L16.414 9H20a1 1 0 1 1 0 2h-6a1 1 0 0 1-1-1V4a1 1 0 1 1 2 0v3.586l4.543-4.543a1 1 0 0 1 1.414 0ZM3 14a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0v-3.586l-4.543 4.543a1 1 0 0 1-1.414-1.414L7.586 15H4a1 1 0 0 1-1-1Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M20.957 3.043a1 1 0 0 1 0 1.414L16.414 9H20a1 1 0 1 1 0 2h-6a1 1 0 0 1-1-1V4a1 1 0 1 1 2 0v3.586l4.543-4.543a1 1 0 0 1 1.414 0ZM3 14a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0v-3.586l-4.543 4.543a1 1 0 0 1-1.414-1.414L7.586 15H4a1 1 0 0 1-1-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 389 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M20.957 3.043a1 1 0 0 1 0 1.414L16.414 9H20a1 1 0 1 1 0 2h-5a2 2 0 0 1-2-2V4a1 1 0 1 1 2 0v3.586l4.543-4.543a1 1 0 0 1 1.414 0ZM3 14a1 1 0 0 1 1-1h5a2 2 0 0 1 2 2v5a1 1 0 1 1-2 0v-3.586l-4.543 4.543a1 1 0 0 1-1.414-1.414L7.586 15H4a1 1 0 0 1-1-1Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M20.957 3.043a1 1 0 0 1 0 1.414L16.414 9H20a1 1 0 1 1 0 2h-5a2 2 0 0 1-2-2V4a1 1 0 1 1 2 0v3.586l4.543-4.543a1 1 0 0 1 1.414 0ZM3 14a1 1 0 0 1 1-1h5a2 2 0 0 1 2 2v5a1 1 0 1 1-2 0v-3.586l-4.543 4.543a1 1 0 0 1-1.414-1.414L7.586 15H4a1 1 0 0 1-1-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 389 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 5a1 1 0 1 1 0-2h6a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0V6.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L17.586 5H14ZM4 13a1 1 0 0 1 1 1v3.586l4.293-4.293a1 1 0 0 1 1.414 1.414L6.414 19H10a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M14 5a1 1 0 1 1 0-2h6a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0V6.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L17.586 5H14ZM4 13a1 1 0 0 1 1 1v3.586l4.293-4.293a1 1 0 0 1 1.414 1.414L6.414 19H10a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 369 B After Width: | Height: | Size: 367 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13 4a1 1 0 0 1 1-1h5a2 2 0 0 1 2 2v5a1 1 0 1 1-2 0V6.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L17.586 5H14a1 1 0 0 1-1-1Zm-9 9a1 1 0 0 1 1 1v3.586l4.293-4.293a1 1 0 0 1 1.414 1.414L6.414 19H10a1 1 0 1 1 0 2H5a2 2 0 0 1-2-2v-5a1 1 0 0 1 1-1Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M13 4a1 1 0 0 1 1-1h5a2 2 0 0 1 2 2v5a1 1 0 1 1-2 0V6.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L17.586 5H14a1 1 0 0 1-1-1Zm-9 9a1 1 0 0 1 1 1v3.586l4.293-4.293a1 1 0 0 1 1.414 1.414L6.414 19H10a1 1 0 1 1 0 2H5a2 2 0 0 1-2-2v-5a1 1 0 0 1 1-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 384 B After Width: | Height: | Size: 381 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a8 8 0 1 0 4.21 14.804 1 1 0 0 1 1.054 1.7A9.958 9.958 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 1.104-.27 2.31-.949 3.243-.716.984-1.849 1.6-3.331 1.465a4.207 4.207 0 0 1-2.93-1.585c-.94 1.21-2.388 1.94-3.985 1.715-2.53-.356-4.04-2.91-3.682-5.458.358-2.547 2.514-4.586 5.044-4.23.905.127 1.68.536 2.286 1.126a1 1 0 0 1 1.964.368l-.515 3.545v.002a2.222 2.222 0 0 0 1.999 2.526c.75.068 1.212-.21 1.533-.65.358-.493.566-1.245.566-2.067a8 8 0 0 0-8-8Zm-.112 5.13c-1.195-.168-2.544.819-2.784 2.529-.24 1.71.784 3.03 1.98 3.198 1.195.168 2.543-.819 2.784-2.529.24-1.71-.784-3.03-1.98-3.198Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a8 8 0 1 0 4.21 14.804 1 1 0 0 1 1.054 1.7A9.96 9.96 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 1.104-.27 2.31-.949 3.243-.716.984-1.849 1.6-3.331 1.465a4.2 4.2 0 0 1-2.93-1.585c-.94 1.21-2.388 1.94-3.985 1.715-2.53-.356-4.04-2.91-3.682-5.458s2.514-4.586 5.044-4.23c.905.127 1.68.536 2.286 1.126a1 1 0 0 1 1.964.368l-.515 3.545v.002a2.22 2.22 0 0 0 1.999 2.526c.75.068 1.212-.21 1.533-.65.358-.493.566-1.245.566-2.067a8 8 0 0 0-8-8Zm-.112 5.13c-1.195-.168-2.544.819-2.784 2.529s.784 3.03 1.98 3.198 2.543-.819 2.784-2.529-.784-3.03-1.98-3.198Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 756 B After Width: | Height: | Size: 713 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6.17 5.004c-.553-.029-.814.107-.937.23-.122.122-.258.383-.23.936.03.552.222 1.28.611 2.15.282.628.655 1.304 1.112 2.005a28.26 28.26 0 0 1 1.72-1.88 28.258 28.258 0 0 1 1.88-1.719 14.886 14.886 0 0 0-2.007-1.112c-.868-.39-1.597-.581-2.15-.61Zm5.83.44c-.985-.688-1.953-1.247-2.863-1.655-.998-.447-1.978-.736-2.863-.782-.885-.047-1.791.148-2.455.812-.664.664-.859 1.57-.812 2.455.046.885.335 1.865.782 2.863.408.91.967 1.878 1.655 2.863-.688.985-1.247 1.953-1.655 2.863-.447.998-.736 1.978-.782 2.863-.047.885.148 1.791.812 2.455.664.663 1.57.859 2.455.812.885-.046 1.865-.335 2.863-.782.91-.408 1.878-.967 2.863-1.655.985.688 1.952 1.247 2.863 1.655.998.447 1.978.736 2.863.782.885.047 1.791-.148 2.455-.812.663-.664.859-1.57.812-2.455-.046-.885-.335-1.865-.782-2.863-.408-.91-.967-1.878-1.655-2.863.688-.985 1.247-1.952 1.655-2.863.447-.998.736-1.978.782-2.863.047-.885-.148-1.791-.812-2.455-.664-.664-1.57-.859-2.455-.812-.885.046-1.865.335-2.863.782-.91.408-1.878.967-2.863 1.655Zm0 2.497A25.9 25.9 0 0 0 9.86 9.86 25.899 25.899 0 0 0 7.94 12c.569.711 1.211 1.431 1.92 2.14.709.709 1.429 1.351 2.14 1.92a25.925 25.925 0 0 0 2.14-1.92A25.925 25.925 0 0 0 16.06 12a25.921 25.921 0 0 0-1.92-2.14A25.904 25.904 0 0 0 12 7.94Zm5.274 2.384a28.232 28.232 0 0 0-1.72-1.88 28.27 28.27 0 0 0-1.88-1.719 14.89 14.89 0 0 1 2.007-1.112c.868-.39 1.597-.581 2.15-.61.552-.029.813.107.936.23.123.122.258.383.23.936-.03.552-.222 1.28-.611 2.15a14.883 14.883 0 0 1-1.112 2.005Zm0 3.35a28.24 28.24 0 0 1-1.72 1.88 28.24 28.24 0 0 1-1.88 1.719c.702.457 1.378.83 2.007 1.112.868.39 1.597.581 2.15.61.552.03.813-.106.936-.23.123-.122.258-.383.23-.935-.03-.553-.222-1.282-.611-2.15a14.888 14.888 0 0 0-1.112-2.006Zm-6.949 3.599a28.23 28.23 0 0 1-1.88-1.72 28.27 28.27 0 0 1-1.719-1.88 14.89 14.89 0 0 0-1.112 2.007c-.39.868-.581 1.597-.61 2.15-.029.552.107.813.23.936.122.123.383.258.936.23.552-.03 1.28-.222 2.15-.611a14.884 14.884 0 0 0 2.005-1.112Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6.17 5.004c-.553-.029-.814.107-.937.23-.122.122-.258.383-.23.936.03.552.222 1.28.611 2.15.282.628.655 1.304 1.112 2.005a28 28 0 0 1 1.72-1.88 28 28 0 0 1 1.88-1.719 15 15 0 0 0-2.007-1.112c-.868-.39-1.597-.581-2.15-.61Zm5.83.44c-.985-.688-1.953-1.247-2.863-1.655-.998-.447-1.978-.736-2.863-.782s-1.791.148-2.455.812-.859 1.57-.812 2.455.335 1.865.782 2.863c.408.91.967 1.878 1.655 2.863-.688.985-1.247 1.953-1.655 2.863-.447.998-.736 1.978-.782 2.863s.148 1.791.812 2.455c.664.663 1.57.859 2.455.812s1.865-.335 2.863-.782c.91-.408 1.878-.967 2.863-1.655.985.688 1.952 1.247 2.863 1.655.998.447 1.978.736 2.863.782s1.791-.148 2.455-.812c.663-.664.859-1.57.812-2.455s-.335-1.865-.782-2.863c-.408-.91-.967-1.878-1.655-2.863.688-.985 1.247-1.952 1.655-2.863.447-.998.736-1.978.782-2.863s-.148-1.791-.812-2.455-1.57-.859-2.455-.812-1.865.335-2.863.782c-.91.408-1.878.967-2.863 1.655Zm0 2.497A26 26 0 0 0 9.86 9.86 26 26 0 0 0 7.94 12a26 26 0 0 0 1.92 2.14A26 26 0 0 0 12 16.06a26 26 0 0 0 2.14-1.92A26 26 0 0 0 16.06 12a26 26 0 0 0-1.92-2.14A26 26 0 0 0 12 7.94Zm5.274 2.384a28 28 0 0 0-1.72-1.88 28 28 0 0 0-1.88-1.719 15 15 0 0 1 2.007-1.112c.868-.39 1.597-.581 2.15-.61s.813.107.936.23c.123.122.258.383.23.936-.03.552-.222 1.28-.611 2.15a15 15 0 0 1-1.112 2.005Zm0 3.35a28 28 0 0 1-1.72 1.88 28 28 0 0 1-1.88 1.719c.702.457 1.378.83 2.007 1.112.868.39 1.597.581 2.15.61s.813-.106.936-.23c.123-.122.258-.383.23-.935-.03-.553-.222-1.282-.611-2.15a15 15 0 0 0-1.112-2.006Zm-6.949 3.599a28 28 0 0 1-1.88-1.72 28 28 0 0 1-1.719-1.88 15 15 0 0 0-1.112 2.007c-.39.868-.581 1.597-.61 2.15s.107.813.23.936c.122.123.383.258.936.23.552-.03 1.28-.222 2.15-.611a15 15 0 0 0 2.005-1.112Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 2a7.307 7.307 0 0 0-7.298 6.943l-.19 3.798-1.321 2.641A1.809 1.809 0 0 0 4.809 18H7.1a5.002 5.002 0 0 0 9.8 0h2.291a1.809 1.809 0 0 0 1.618-2.618l-1.32-2.641-.19-3.798A7.308 7.308 0 0 0 12 2Zm0 18a3.001 3.001 0 0 1-2.83-2h5.66A3.001 3.001 0 0 1 12 20Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 2a7.307 7.307 0 0 0-7.298 6.943l-.19 3.798-1.321 2.641A1.81 1.81 0 0 0 4.809 18H7.1a5.002 5.002 0 0 0 9.8 0h2.291a1.81 1.81 0 0 0 1.618-2.618l-1.32-2.641-.19-3.798A7.31 7.31 0 0 0 12 2Zm0 18a3 3 0 0 1-2.83-2h5.66A3 3 0 0 1 12 20Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 376 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.702 8.943a7.307 7.307 0 0 1 14.596 0l.19 3.798 1.321 2.641A1.809 1.809 0 0 1 19.191 18H16.9a5.002 5.002 0 0 1-9.8 0H4.809a1.809 1.809 0 0 1-1.618-2.618l1.32-2.641.19-3.798ZM9.17 18a3.001 3.001 0 0 0 5.658 0H9.171ZM12 4a5.307 5.307 0 0 0-5.3 5.042l-.19 3.798a2 2 0 0 1-.21.795L5.119 16h13.764l-1.183-2.365a2 2 0 0 1-.208-.795l-.19-3.798A5.308 5.308 0 0 0 12 4Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.702 8.943a7.307 7.307 0 0 1 14.596 0l.19 3.798 1.321 2.641A1.81 1.81 0 0 1 19.191 18H16.9a5.002 5.002 0 0 1-9.8 0H4.809a1.81 1.81 0 0 1-1.618-2.618l1.32-2.641.19-3.798ZM9.17 18a3.001 3.001 0 0 0 5.658 0H9.171ZM12 4a5.307 5.307 0 0 0-5.3 5.042l-.19 3.798a2 2 0 0 1-.21.795L5.119 16h13.764L17.7 13.635a2 2 0 0 1-.208-.795l-.19-3.798A5.31 5.31 0 0 0 12 4Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 498 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="m19.785 8.815 1.034 7.761L7.595 3.352a7.853 7.853 0 0 1 12.19 5.463ZM4 19h3.354c.904 1.748 2.607 3 4.646 3 2.038 0 3.742-1.252 4.646-3h.94l2.707 2.707a1 1 0 0 0 1.414-1.414l-18-18a1 1 0 0 0-1.414 1.414l2.666 2.666a7.842 7.842 0 0 0-.743 2.442l-1.207 9.053A1 1 0 0 0 4 19Zm8 1c-.823 0-1.613-.363-2.222-1h4.443c-.608.637-1.398 1-2.221 1Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="m19.785 8.815 1.034 7.761L7.595 3.352a7.853 7.853 0 0 1 12.19 5.463ZM4 19h3.354c.904 1.748 2.607 3 4.646 3s3.742-1.252 4.646-3h.94l2.707 2.707a1 1 0 0 0 1.414-1.414l-18-18a1 1 0 0 0-1.414 1.414l2.666 2.666a7.8 7.8 0 0 0-.743 2.442l-1.207 9.053A1 1 0 0 0 4 19Zm8 1c-.823 0-1.613-.363-2.222-1h4.443c-.608.637-1.398 1-2.221 1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 478 B After Width: | Height: | Size: 466 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.293 2.293a1 1 0 0 1 1.414 0l18 18a1 1 0 0 1-1.414 1.414L17.586 19h-.94c-.904 1.748-2.607 3-4.646 3-2.039 0-3.742-1.252-4.646-3H4a1 1 0 0 1-.991-1.132l1.207-9.053c.116-.87.372-1.69.743-2.442L2.293 3.707a1 1 0 0 1 0-1.414Zm4.19 5.604c-.134.376-.23.772-.285 1.183L5.142 17h10.444L6.483 7.897ZM9.778 19c.61.637 1.399 1 2.222 1s1.613-.363 2.222-1H9.778ZM8.834 2.666a7.853 7.853 0 0 1 10.95 6.15l.645 4.832a1 1 0 0 1-1.983.265l-.644-4.833A5.853 5.853 0 0 0 9.64 4.495a1 1 0 0 1-.807-1.83Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.293 2.293a1 1 0 0 1 1.414 0l18 18a1 1 0 0 1-1.414 1.414L17.586 19h-.94c-.904 1.748-2.607 3-4.646 3s-3.742-1.252-4.646-3H4a1 1 0 0 1-.991-1.132l1.207-9.053c.116-.87.372-1.69.743-2.442L2.293 3.707a1 1 0 0 1 0-1.414Zm4.19 5.604q-.202.565-.285 1.183L5.142 17h10.444L6.483 7.897ZM9.778 19c.61.637 1.399 1 2.222 1s1.613-.363 2.222-1H9.778ZM8.834 2.666a7.853 7.853 0 0 1 10.95 6.15l.645 4.832a1 1 0 0 1-1.983.265l-.644-4.833A5.853 5.853 0 0 0 9.64 4.495a1 1 0 0 1-.807-1.83Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 628 B After Width: | Height: | Size: 613 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 2a7.853 7.853 0 0 0-7.784 6.815l-1.207 9.053A1 1 0 0 0 4 19h3.354c.904 1.748 2.607 3 4.646 3 2.039 0 3.742-1.252 4.646-3H20a1 1 0 0 0 .991-1.132l-1.207-9.053A7.853 7.853 0 0 0 12 2Zm2.222 17H9.778c.61.637 1.399 1 2.222 1s1.613-.363 2.222-1Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 2a7.85 7.85 0 0 0-7.784 6.815l-1.207 9.053A1 1 0 0 0 4 19h3.354c.904 1.748 2.607 3 4.646 3s3.742-1.252 4.646-3H20a1 1 0 0 0 .991-1.132l-1.207-9.053A7.85 7.85 0 0 0 12 2Zm2.222 17H9.778c.61.637 1.399 1 2.222 1s1.613-.363 2.222-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 375 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.216 8.815a7.853 7.853 0 0 1 15.568 0l1.207 9.053A1 1 0 0 1 20 19h-3.354c-.904 1.748-2.607 3-4.646 3-2.039 0-3.742-1.252-4.646-3H4a1 1 0 0 1-.991-1.132l1.207-9.053ZM9.778 19c.61.637 1.399 1 2.222 1s1.613-.363 2.222-1H9.778ZM12 4a5.853 5.853 0 0 0-5.802 5.08L5.142 17h13.716l-1.056-7.92A5.853 5.853 0 0 0 12 4Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.216 8.815a7.853 7.853 0 0 1 15.568 0l1.207 9.053A1 1 0 0 1 20 19h-3.354c-.904 1.748-2.607 3-4.646 3s-3.742-1.252-4.646-3H4a1 1 0 0 1-.991-1.132l1.207-9.053ZM9.778 19c.61.637 1.399 1 2.222 1s1.613-.363 2.222-1H9.778ZM12 4a5.85 5.85 0 0 0-5.802 5.08L5.142 17h13.716l-1.056-7.92A5.85 5.85 0 0 0 12 4Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 443 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M5.002 17.036V5h14v12.036h-3.986a1 1 0 0 0-.639.23l-2.375 1.968-2.344-1.965a1 1 0 0 0-.643-.233H5.002ZM20.002 3h-16a1 1 0 0 0-1 1v14.036a1 1 0 0 0 1 1h4.65l2.704 2.266a1 1 0 0 0 1.28.004l2.74-2.27h4.626a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1Zm-7.878 3.663c-1.39 0-2.5 1.135-2.5 2.515a1 1 0 0 0 2 0c0-.294.232-.515.5-.515a.507.507 0 0 1 .489.6.174.174 0 0 1-.027.048 1.1 1.1 0 0 1-.267.226c-.508.345-1.128.923-1.286 1.978a1 1 0 1 0 1.978.297.762.762 0 0 1 .14-.359c.063-.086.155-.169.293-.262.436-.297 1.18-.885 1.18-2.013 0-1.38-1.11-2.515-2.5-2.515ZM12 15.75a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M5.002 17.036V5h14v12.036h-3.986a1 1 0 0 0-.639.23l-2.375 1.968-2.344-1.965a1 1 0 0 0-.643-.233H5.002ZM20.002 3h-16a1 1 0 0 0-1 1v14.036a1 1 0 0 0 1 1h4.65l2.704 2.266a1 1 0 0 0 1.28.004l2.74-2.27h4.626a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1Zm-7.878 3.663c-1.39 0-2.5 1.135-2.5 2.515a1 1 0 0 0 2 0c0-.294.232-.515.5-.515a.507.507 0 0 1 .489.6.2.2 0 0 1-.027.048 1.1 1.1 0 0 1-.267.226c-.508.345-1.128.923-1.286 1.978a1 1 0 1 0 1.978.297.76.76 0 0 1 .14-.359c.063-.086.155-.169.293-.262.436-.297 1.18-.885 1.18-2.013 0-1.38-1.11-2.515-2.5-2.515ZM12 15.75a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 732 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 4a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4Zm11.543 7.293a1 1 0 0 1 1.414 0 1 1 0 0 0 1.414-1.414 3 3 0 1 0 0 4.242 1 1 0 0 0-1.414-1.414 1 1 0 0 1-1.414-1.414Zm-6 0a1 1 0 0 1 1.414 0 1 1 0 0 0 1.414-1.414 3 3 0 1 0 0 4.243 1 1 0 0 0-1.414-1.415 1 1 0 0 1-1.414-1.414Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3 4a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4Zm11.543 7.293a1 1 0 0 1 1.414 0 1 1 0 0 0 1.414-1.414 3 3 0 1 0 0 4.242 1 1 0 0 0-1.414-1.414 1 1 0 0 1-1.414-1.414Zm-6 0a1 1 0 0 1 1.414 0 1 1 0 0 0 1.414-1.414 3 3 0 1 0 0 4.243 1 1 0 0 0-1.414-1.415 1 1 0 0 1-1.414-1.414Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 440 B After Width: | Height: | Size: 438 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 4a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4Zm2 1v14h14V5H5Zm10.957 6.293a1 1 0 1 0 0 1.414 1 1 0 0 1 1.414 1.414 3 3 0 1 1 0-4.242 1 1 0 0 1-1.414 1.414Zm-6.331-.22a1 1 0 1 0 .331 1.634 1 1 0 0 1 1.414 1.414 3 3 0 1 1 0-4.242 1 1 0 0 1-1.414 1.414.994.994 0 0 0-.331-.22Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3 4a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4Zm2 1v14h14V5H5Zm10.957 6.293a1 1 0 1 0 0 1.414 1 1 0 0 1 1.414 1.414 3 3 0 1 1 0-4.242 1 1 0 0 1-1.414 1.414Zm-6.331-.22a1 1 0 1 0 .331 1.634 1 1 0 0 1 1.414 1.414 3 3 0 1 1 0-4.242 1 1 0 0 1-1.414 1.414 1 1 0 0 0-.331-.22Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 443 B After Width: | Height: | Size: 437 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M13.832 1.014a1 1 0 0 1 1.154.818L14 2l.986-.168v.003l.001.005.002.014.007.045.021.156c.017.13.035.312.048.527.025.42.028 1.01-.082 1.6-.127.69-.447 1.31-.701 1.726a7.107 7.107 0 0 1-.498.712l-.01.014-.004.005-.002.001v.002L13 6l.767.642a1 1 0 0 1-1.535-1.282l.002-.003.017-.02a5.13 5.13 0 0 0 .324-.47c.198-.325.378-.705.442-1.049.068-.37.071-.78.051-1.12a6.268 6.268 0 0 0-.05-.504l-.004-.025m.818-1.155a1 1 0 0 0-.818 1.155Zm5.257 1.545a1 1 0 0 1 .602 1.28l-.45 1.25a1 1 0 0 1-1.882-.678l.45-1.25a1 1 0 0 1 1.28-.602ZM6.524 7.136a2 2 0 0 1 3.294-.732l7.778 7.778a2 2 0 0 1-.732 3.294L4.653 21.91c-1.596.579-3.142-.967-2.563-2.563L6.524 7.136Zm9.658 8.46L8.404 7.818 3.97 20.03l12.212-4.434Zm5.712-8.543a1 1 0 0 1-.447 1.341l-1 .5a1 1 0 1 1-.894-1.788l1-.5a1 1 0 0 1 1.341.447Zm-4.687-.26a1 1 0 0 1 0 1.414l-1 1a1 1 0 1 1-1.414-1.414l1-1a1 1 0 0 1 1.414 0Zm-.206 4.165A1 1 0 0 1 18.042 10L18 11l.042-1 .003.001h.014l.035.003.117.008a7.693 7.693 0 0 1 1.594.306c.423.135.861.352 1.168.516a11.873 11.873 0 0 1 .508.288l.032.02.01.006.004.002L21 12l.527-.85a1 1 0 0 1-1.054 1.7l-.005-.003-.023-.014a7.477 7.477 0 0 0-.415-.236 5.497 5.497 0 0 0-.835-.374A5.684 5.684 0 0 0 17.973 12l-.015-.002h-.002a1 1 0 0 1-.955-1.041Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M13.832 1.014a1 1 0 0 1 1.154.818L14 2l.986-.168v.003l.001.005.002.014.007.045.021.156c.017.13.035.312.048.527.025.42.028 1.01-.082 1.6-.127.69-.447 1.31-.701 1.726a7 7 0 0 1-.498.712l-.01.014-.004.005-.002.001v.002L13 6l.767.642a1 1 0 0 1-1.535-1.282l.002-.003.017-.02a5 5 0 0 0 .324-.47c.198-.325.378-.705.442-1.049.068-.37.071-.78.051-1.12a6 6 0 0 0-.05-.504l-.004-.025m.818-1.155a1 1 0 0 0-.818 1.155Zm5.257 1.545a1 1 0 0 1 .602 1.28l-.45 1.25a1 1 0 0 1-1.882-.678l.45-1.25a1 1 0 0 1 1.28-.602ZM6.524 7.136a2 2 0 0 1 3.294-.732l7.778 7.778a2 2 0 0 1-.732 3.294L4.653 21.91c-1.596.579-3.142-.967-2.563-2.563L6.524 7.136Zm9.658 8.46L8.404 7.818 3.97 20.03l12.212-4.434Zm5.712-8.543a1 1 0 0 1-.447 1.341l-1 .5a1 1 0 1 1-.894-1.788l1-.5a1 1 0 0 1 1.341.447Zm-4.687-.26a1 1 0 0 1 0 1.414l-1 1a1 1 0 1 1-1.414-1.414l1-1a1 1 0 0 1 1.414 0Zm-.206 4.165A1 1 0 0 1 18.042 10L18 11l.042-1 .003.001h.014l.035.003.117.008a7.7 7.7 0 0 1 1.594.306c.423.135.861.352 1.168.516a12 12 0 0 1 .508.288l.032.02.01.006.004.002L21 12l.527-.85a1 1 0 0 1-1.054 1.7l-.005-.003-.023-.014a8 8 0 0 0-.415-.236 5.5 5.5 0 0 0-.835-.374A5.7 5.7 0 0 0 17.973 12l-.015-.002h-.002a1 1 0 0 1-.955-1.041Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a8 8 0 0 0-6.32 12.906L16.906 5.68A7.962 7.962 0 0 0 12 4Zm6.32 3.094L7.094 18.32A8 8 0 0 0 18.32 7.094ZM2 12C2 6.477 6.477 2 12 2a9.972 9.972 0 0 1 7.071 2.929A9.972 9.972 0 0 1 22 12c0 5.523-4.477 10-10 10a9.972 9.972 0 0 1-7.071-2.929A9.972 9.972 0 0 1 2 12Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a8 8 0 0 0-6.32 12.906L16.906 5.68A7.96 7.96 0 0 0 12 4Zm6.32 3.094L7.094 18.32A8 8 0 0 0 18.32 7.094ZM2 12C2 6.477 6.477 2 12 2a9.97 9.97 0 0 1 7.071 2.929A9.97 9.97 0 0 1 22 12c0 5.523-4.477 10-10 10a9.97 9.97 0 0 1-7.071-2.929A9.97 9.97 0 0 1 2 12Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 409 B After Width: | Height: | Size: 399 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M8.17 4A3.001 3.001 0 0 1 11 2h2c1.306 0 2.418.835 2.83 2H17a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h1.17ZM8 6H7a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1h-1v1a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V6Zm6 0V5a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v1h4Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M8.17 4A3 3 0 0 1 11 2h2c1.306 0 2.418.835 2.83 2H17a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h1.17ZM8 6H7a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1h-1v1a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V6Zm6 0V5a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v1h4Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 422 B After Width: | Height: | Size: 414 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M3.004 4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2v5a1 1 0 0 0 .43.822c.57.395 1.176.031 1.685-.255.428-.24.998-.614 1.569-1.15 1.154-1.082 2.316-2.832 2.316-5.417V5a1 1 0 0 0-1-1h-7ZM14.004 4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2v5a1 1 0 0 0 .43.822c.57.395 1.176.031 1.685-.255.428-.24.998-.614 1.569-1.15 1.154-1.082 2.316-2.832 2.316-5.417V5a1 1 0 0 0-1-1h-7Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M3.004 4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2v5a1 1 0 0 0 .43.822c.57.395 1.176.031 1.685-.255.428-.24.998-.614 1.569-1.15 1.154-1.082 2.316-2.832 2.316-5.417V5a1 1 0 0 0-1-1h-7Zm11 0a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2v5a1 1 0 0 0 .43.822c.57.395 1.176.031 1.685-.255.428-.24.998-.614 1.569-1.15 1.154-1.082 2.316-2.832 2.316-5.417V5a1 1 0 0 0-1-1h-7Z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 446 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.004 5a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v8c0 2.585-1.162 4.335-2.316 5.417-.571.536-1.14.91-1.569 1.15a7.01 7.01 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001L6.004 19l.351.936A1 1 0 0 1 5.004 19v-5h-2a1 1 0 0 1-1-1V5Zm5 12.234c.104-.085.21-.177.316-.276.846-.793 1.684-2.043 1.684-3.958V6h-5v6h2a1 1 0 0 1 1 1v4.234Zm6-12.234a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v8c0 2.585-1.162 4.335-2.316 5.417-.571.536-1.14.91-1.569 1.15a7.018 7.018 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001-.352-.936.351.936A1 1 0 0 1 16.004 19v-5h-2a1 1 0 0 1-1-1V5Zm5 12.234V13a1 1 0 0 0-1-1h-2V6h5v7c0 1.915-.838 3.165-1.684 3.958-.106.1-.212.191-.316.276Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.004 5a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v8c0 2.585-1.162 4.335-2.316 5.417-.571.536-1.14.91-1.569 1.15a7 7 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001L6.004 19l.351.936A1 1 0 0 1 5.004 19v-5h-2a1 1 0 0 1-1-1V5Zm5 12.234q.156-.127.316-.276c.846-.793 1.684-2.043 1.684-3.958V6h-5v6h2a1 1 0 0 1 1 1v4.234Zm6-12.234a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v8c0 2.585-1.162 4.335-2.316 5.417-.571.536-1.14.91-1.569 1.15a7 7 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001-.352-.936.351.936A1 1 0 0 1 16.004 19v-5h-2a1 1 0 0 1-1-1V5Zm5 12.234V13a1 1 0 0 0-1-1h-2V6h5v7c0 1.915-.838 3.165-1.684 3.958q-.16.15-.316.276Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 775 B After Width: | Height: | Size: 747 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.003 5.999a2 2 0 0 1 2-1.999h5c1.104 0 2 .893 2 1.999V13c0 2.585-1.16 4.335-2.315 5.417-.571.536-1.14.91-1.569 1.15a7.01 7.01 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001L6.004 19l.351.936a1 1 0 0 1-1.351-.935L5 14H4a2 2 0 0 1-2-2.001l.002-6Zm5 11.236L7 12.999A1 1 0 0 0 6 12H4l.003-6h5v7c0 1.915-.837 3.165-1.683 3.958-.106.1-.213.192-.317.277Zm6-11.235a2 2 0 0 1 2-2h5c1.104 0 2 .893 2 1.999V13c0 2.585-1.16 4.335-2.315 5.417-.571.536-1.14.91-1.569 1.15a7.018 7.018 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001-.352-.936.351.936A1 1 0 0 1 16.004 19v-5h-1a2 2 0 0 1-2-2V6Zm7 0h-5v6h2a1 1 0 0 1 1 1v4.234c.105-.085.211-.177.317-.276.846-.793 1.684-2.043 1.684-3.958V6Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.003 5.999a2 2 0 0 1 2-1.999h5c1.104 0 2 .893 2 1.999V13c0 2.585-1.16 4.335-2.315 5.417-.571.536-1.14.91-1.569 1.15a7 7 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001L6.004 19l.351.936a1 1 0 0 1-1.351-.935L5 14H4a2 2 0 0 1-2-2.001l.002-6Zm5 11.236L7 12.999A1 1 0 0 0 6 12H4l.003-6h5v7c0 1.915-.837 3.165-1.683 3.958q-.16.15-.317.277Zm6-11.235a2 2 0 0 1 2-2h5c1.104 0 2 .893 2 1.999V13c0 2.585-1.16 4.335-2.315 5.417-.571.536-1.14.91-1.569 1.15a7 7 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001-.352-.936.351.936A1 1 0 0 1 16.004 19v-5h-1a2 2 0 0 1-2-2V6Zm7 0h-5v6h2a1 1 0 0 1 1 1v4.234q.158-.127.317-.276c.846-.793 1.684-2.043 1.684-3.958V6Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 821 B After Width: | Height: | Size: 791 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 12c0-4.09 3.527-7.5 8-7.5s8 3.41 8 7.5c0 1.579-.419 2.056-.708 2.236-.388.241-1.031.286-2.058.153-.33-.043-.652-.096-.991-.152a65.905 65.905 0 0 0-.531-.087c-.52-.081-1.077-.156-1.61-.164-1.065-.016-2.336.245-2.996 1.567-.418.834-.295 1.67-.078 2.314.18.534.47 1.055.683 1.437v.001l.097.175.01.018C7.432 19.407 4 16.033 4 12Zm8-9.5C6.532 2.5 2 6.7 2 12s4.532 9.5 10 9.5c.401 0 .812-.04 1.166-.193.41-.176.761-.517.866-1.028.085-.416-.03-.796-.118-1.029a5.981 5.981 0 0 0-.351-.73l-.12-.215c-.215-.392-.403-.73-.52-1.078-.13-.387-.111-.614-.029-.78.146-.291.404-.473 1.178-.461.385.005.825.06 1.329.14.15.023.308.05.47.077.36.059.742.122 1.105.17 1.021.132 2.325.213 3.373-.439C21.496 15.22 22 13.874 22 12c0-5.3-4.532-9.5-10-9.5Zm3.5 8.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM9 12.25a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm1.5-2.75a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 12c0-4.09 3.527-7.5 8-7.5s8 3.41 8 7.5c0 1.579-.419 2.056-.708 2.236-.388.241-1.031.286-2.058.153-.33-.043-.652-.096-.991-.152l-.531-.087c-.52-.081-1.077-.156-1.61-.164-1.065-.016-2.336.245-2.996 1.567-.418.834-.295 1.67-.078 2.314.18.534.47 1.055.683 1.437v.001l.097.175.01.018C7.432 19.407 4 16.033 4 12Zm8-9.5C6.532 2.5 2 6.7 2 12s4.532 9.5 10 9.5c.401 0 .812-.04 1.166-.193.41-.176.761-.517.866-1.028.085-.416-.03-.796-.118-1.029a6 6 0 0 0-.351-.73l-.12-.215c-.215-.392-.403-.73-.52-1.078-.13-.387-.111-.614-.029-.78.146-.291.404-.473 1.178-.461.385.005.825.06 1.329.14q.226.035.47.077c.36.059.742.122 1.105.17 1.021.132 2.325.213 3.373-.439C21.496 15.22 22 13.874 22 12c0-5.3-4.532-9.5-10-9.5Zm3.5 8.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM9 12.25a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm1.5-2.75a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1011 B After Width: | Height: | Size: 980 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.4 9.493C4.14 10.28 4 11.124 4 12a8 8 0 1 0 10.899-7.459l-.953 3.81a1 1 0 0 1-.726.727l-3.444.866-.772 1.533a1 1 0 0 1-1.493.35L4.4 9.493Zm.883-1.84L7.756 9.51l.44-.874a1 1 0 0 1 .649-.52l3.306-.832.807-3.227a7.993 7.993 0 0 0-7.676 3.597ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm8.43.162a1 1 0 0 1 .77-.29l1.89.121a1 1 0 0 1 .494.168l2.869 1.928a1 1 0 0 1 .336 1.277l-.973 1.946a1 1 0 0 1-.894.553h-2.92a1 1 0 0 1-.831-.445L9.225 14.5a1 1 0 0 1 .126-1.262l1.08-1.076Zm.915 1.913.177-.177 1.171.074 1.914 1.286-.303.607h-1.766l-1.194-1.79Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.4 9.493C4.14 10.28 4 11.124 4 12a8 8 0 1 0 10.899-7.459l-.953 3.81a1 1 0 0 1-.726.727l-3.444.866-.772 1.533a1 1 0 0 1-1.493.35L4.4 9.493Zm.883-1.84L7.756 9.51l.44-.874a1 1 0 0 1 .649-.52l3.306-.832.807-3.227a7.99 7.99 0 0 0-7.676 3.597ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm8.43.162a1 1 0 0 1 .77-.29l1.89.121a1 1 0 0 1 .494.168l2.869 1.928a1 1 0 0 1 .336 1.277l-.973 1.946a1 1 0 0 1-.894.553h-2.92a1 1 0 0 1-.831-.445L9.225 14.5a1 1 0 0 1 .126-1.262l1.08-1.076Zm.915 1.913.177-.177 1.171.074 1.914 1.286-.303.607h-1.766l-1.194-1.79Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 713 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Zm8-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2ZM9.351 12.13c1.898-1.507 2.176-2.95 1.613-3.83a1.524 1.524 0 0 0-1.225-.707 1.562 1.562 0 0 0-1.218.53 1.561 1.561 0 0 0-1.326-.082c-.456.186-.8.588-.91 1.083-.227 1.02.527 2.282 2.826 3.048a.256.256 0 0 0 .24-.043Zm5.538.042c2.299-.766 3.053-2.027 2.826-3.048a1.524 1.524 0 0 0-.91-1.082 1.561 1.561 0 0 0-1.326.081 1.562 1.562 0 0 0-1.217-.53 1.524 1.524 0 0 0-1.226.706c-.563.881-.285 2.325 1.613 3.83.068.054.158.07.24.043Zm1.072 2.38a4 4 0 0 1-7.924 0c-.04-.293.218-.525.514-.499 2.309.206 4.587.206 6.896 0 .296-.026.555.206.514.5Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Zm8-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2ZM9.351 12.13c1.898-1.507 2.176-2.95 1.613-3.83a1.52 1.52 0 0 0-1.225-.707 1.56 1.56 0 0 0-1.218.53 1.56 1.56 0 0 0-1.326-.082c-.456.186-.8.588-.91 1.083-.227 1.02.527 2.282 2.826 3.048a.26.26 0 0 0 .24-.043Zm5.538.042c2.299-.766 3.053-2.027 2.826-3.048a1.52 1.52 0 0 0-.91-1.082 1.56 1.56 0 0 0-1.326.081 1.56 1.56 0 0 0-1.217-.53 1.52 1.52 0 0 0-1.226.706c-.563.881-.285 2.325 1.613 3.83.068.054.158.07.24.043Zm1.072 2.38a4 4 0 0 1-7.924 0c-.04-.293.218-.525.514-.499 2.309.206 4.587.206 6.896 0 .296-.026.555.206.514.5Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 786 B After Width: | Height: | Size: 771 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6.343 6.343a8 8 0 1 1 11.314 11.314A8 8 0 0 1 6.343 6.343ZM19.071 4.93c-3.905-3.905-10.237-3.905-14.142 0-3.905 3.905-3.905 10.237 0 14.142 3.905 3.905 10.237 3.905 14.142 0 3.905-3.905 3.905-10.237 0-14.142Zm-3.537 9.535a5 5 0 0 0-7.07 0 1 1 0 1 0 1.413 1.415 3 3 0 0 1 4.243 0 1 1 0 0 0 1.414-1.415ZM16 9.5c0 .828-.56 1.5-1.25 1.5s-1.25-.672-1.25-1.5.56-1.5 1.25-1.5S16 8.672 16 9.5ZM9.25 11c.69 0 1.25-.672 1.25-1.5S9.94 8 9.25 8 8 8.672 8 9.5 8.56 11 9.25 11Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6.343 6.343a8 8 0 1 1 11.314 11.314A8 8 0 0 1 6.343 6.343ZM19.071 4.93c-3.905-3.905-10.237-3.905-14.142 0s-3.905 10.237 0 14.142 10.237 3.905 14.142 0 3.905-10.237 0-14.142Zm-3.537 9.535a5 5 0 0 0-7.07 0 1 1 0 1 0 1.413 1.415 3 3 0 0 1 4.243 0 1 1 0 0 0 1.414-1.415ZM16 9.5c0 .828-.56 1.5-1.25 1.5s-1.25-.672-1.25-1.5.56-1.5 1.25-1.5S16 8.672 16 9.5ZM9.25 11c.69 0 1.25-.672 1.25-1.5S9.94 8 9.25 8 8 8.672 8 9.5 8.56 11 9.25 11Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 607 B After Width: | Height: | Size: 572 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M17.657 6.343A8 8 0 1 0 6.343 17.657 8 8 0 0 0 17.657 6.343ZM4.929 4.93c3.905-3.905 10.237-3.905 14.142 0 3.905 3.905 3.905 10.237 0 14.142-3.905 3.905-10.237 3.905-14.142 0-3.905-3.905-3.905-10.237 0-14.142Zm3.536 9.192a1 1 0 0 1 1.414 0 3 3 0 0 0 4.243 0 1 1 0 0 1 1.414 1.415 5 5 0 0 1-7.071 0 1 1 0 0 1 0-1.415Z M10.5 9.5c0 .828-.56 1.5-1.25 1.5S8 10.328 8 9.5 8.56 8 9.25 8s1.25.672 1.25 1.5ZM16 9.5c0 .828-.56 1.5-1.25 1.5s-1.25-.672-1.25-1.5.56-1.5 1.25-1.5S16 8.672 16 9.5Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M17.657 6.343A8 8 0 1 0 6.343 17.657 8 8 0 0 0 17.657 6.343ZM4.929 4.93c3.905-3.905 10.237-3.905 14.142 0s3.905 10.237 0 14.142-10.237 3.905-14.142 0-3.905-10.237 0-14.142Zm3.536 9.192a1 1 0 0 1 1.414 0 3 3 0 0 0 4.243 0 1 1 0 0 1 1.414 1.415 5 5 0 0 1-7.071 0 1 1 0 0 1 0-1.415ZM10.5 9.5c0 .828-.56 1.5-1.25 1.5S8 10.328 8 9.5 8.56 8 9.25 8s1.25.672 1.25 1.5Zm5.5 0c0 .828-.56 1.5-1.25 1.5s-1.25-.672-1.25-1.5.56-1.5 1.25-1.5S16 8.672 16 9.5Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 623 B After Width: | Height: | Size: 586 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 11.708 2.654 4.06A.998.998 0 0 1 3 4h18c.122 0 .238.022.346.061L12 11.708ZM2 19V6.11l9.367 7.664a1 1 0 0 0 1.266 0L22 6.11V19a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 11.708 2.654 4.06A1 1 0 0 1 3 4h18q.183.001.346.061L12 11.708ZM2 19V6.11l9.367 7.664a1 1 0 0 0 1.266 0L22 6.11V19a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 291 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.568 4h14.864c.252 0 .498 0 .706.017.229.019.499.063.77.201a2 2 0 0 1 .874.874c.138.271.182.541.201.77.017.208.017.454.017.706v10.864c0 .252 0 .498-.017.706a2.022 2.022 0 0 1-.201.77 2 2 0 0 1-.874.874 2.022 2.022 0 0 1-.77.201c-.208.017-.454.017-.706.017H4.568c-.252 0-.498 0-.706-.017a2.022 2.022 0 0 1-.77-.201 2 2 0 0 1-.874-.874 2.022 2.022 0 0 1-.201-.77C2 17.93 2 17.684 2 17.432V6.568c0-.252 0-.498.017-.706.019-.229.063-.499.201-.77a2 2 0 0 1 .874-.874c.271-.138.541-.182.77-.201C4.07 4 4.316 4 4.568 4Zm.456 2L12 11.708 18.976 6H5.024ZM20 7.747l-6.733 5.509a2 2 0 0 1-2.534 0L4 7.746V17.4a8.187 8.187 0 0 0 .011.589h.014c.116.01.278.011.575.011h14.8a8.207 8.207 0 0 0 .589-.012v-.013c.01-.116.011-.279.011-.575V7.747Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.568 4h14.864c.252 0 .498 0 .706.017.229.019.499.063.77.201a2 2 0 0 1 .874.874c.138.271.182.541.201.77.017.208.017.454.017.706v10.864c0 .252 0 .498-.017.706a2 2 0 0 1-.201.77 2 2 0 0 1-.874.874 2 2 0 0 1-.77.201c-.208.017-.454.017-.706.017H4.568c-.252 0-.498 0-.706-.017a2 2 0 0 1-.77-.201 2 2 0 0 1-.874-.874 2 2 0 0 1-.201-.77C2 17.93 2 17.684 2 17.432V6.568c0-.252 0-.498.017-.706a2 2 0 0 1 .201-.77 2 2 0 0 1 .874-.874 2 2 0 0 1 .77-.201C4.07 4 4.316 4 4.568 4Zm.456 2L12 11.708 18.976 6H5.024ZM20 7.747l-6.733 5.509a2 2 0 0 1-2.534 0L4 7.746V17.4a8 8 0 0 0 .011.589h.014c.116.01.278.011.575.011h14.8a8 8 0 0 0 .589-.012v-.013c.01-.116.011-.279.011-.575V7.747Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 871 B After Width: | Height: | Size: 809 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 2a1 1 0 0 1 .889.542l1.679 3.259 3.491-1.117a1 1 0 0 1 1.257 1.257L18.2 9.432l3.259 1.679a1 1 0 0 1 0 1.778l-3.124 1.61 2.609 5.098a1 1 0 0 1-1.346 1.346l-5.098-2.61-1.61 3.125a1 1 0 0 1-1.778 0l-1.679-3.259-3.491 1.117a1 1 0 0 1-1.257-1.257L5.8 14.568l-3.259-1.679a1 1 0 0 1 0-1.778l3.124-1.61-2.609-5.098a1 1 0 0 1 1.346-1.346l5.098 2.61-.455.89.455-.89 1.61-3.125A1 1 0 0 1 12 2Zm0 3.183-.72 1.4a2 2 0 0 1-2.69.864L6.248 6.248 7.447 8.59a2 2 0 0 1-.865 2.69L5.183 12l1.534.79a2 2 0 0 1 .989 2.387L7.18 16.82l1.643-.526a2 2 0 0 1 2.387.99l.79 1.533.72-1.4a2 2 0 0 1 2.69-.864l2.342 1.199-1.199-2.342a2 2 0 0 1 .864-2.69l1.4-.72-1.534-.79a2 2 0 0 1-.989-2.387l.526-1.643-1.643.526a2 2 0 0 1-2.387-.99L12 5.184Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 2a1 1 0 0 1 .889.542l1.679 3.259 3.491-1.117a1 1 0 0 1 1.257 1.257L18.2 9.432l3.259 1.679a1 1 0 0 1 0 1.778l-3.124 1.61 2.609 5.098a1 1 0 0 1-1.346 1.346l-5.098-2.61-1.61 3.125a1 1 0 0 1-1.778 0l-1.679-3.259-3.491 1.117a1 1 0 0 1-1.257-1.257L5.8 14.568l-3.259-1.679a1 1 0 0 1 0-1.778l3.124-1.61-2.609-5.098a1 1 0 0 1 1.346-1.346L9.5 5.667l-.455.89.455-.89 1.61-3.125A1 1 0 0 1 12 2Zm0 3.183-.72 1.4a2 2 0 0 1-2.69.864L6.248 6.248 7.447 8.59a2 2 0 0 1-.865 2.69L5.183 12l1.534.79a2 2 0 0 1 .989 2.387L7.18 16.82l1.643-.526a2 2 0 0 1 2.387.99l.79 1.533.72-1.4a2 2 0 0 1 2.69-.864l2.342 1.199-1.199-2.342a2 2 0 0 1 .864-2.69l1.4-.72-1.534-.79a2 2 0 0 1-.989-2.387l.526-1.643-1.643.526a2 2 0 0 1-2.387-.99L12 5.184Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 858 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.293 2.293a1 1 0 0 1 1.414 0L7.335 5.92l.03.03 3.22 3.222 4.243 4.242 3.22 3.22.03.03 3.63 3.629a1 1 0 0 1-1.415 1.414l-3.09-3.09c-2.65 1.478-5.625 1.778-8.421.869-3.039-.987-5.779-3.37-7.67-7.027a1 1 0 0 1 0-.918c1.086-2.1 2.452-3.78 3.996-5.019L2.293 3.707a1 1 0 0 1 0-1.414Zm4.24 5.654 2.021 2.021a4 4 0 0 0 5.478 5.478l1.688 1.688c-2.042.982-4.246 1.124-6.32.45-2.34-.76-4.594-2.586-6.265-5.584.97-1.739 2.135-3.083 3.398-4.053Zm3.535 3.535 2.45 2.45a2 2 0 0 1-2.45-2.45Zm.81-5.405c3.573-.49 7.45 1.369 9.987 5.923a14.797 14.797 0 0 1-1.347 2.02 1 1 0 1 0 1.564 1.247 17.078 17.078 0 0 0 1.806-2.808 1 1 0 0 0 0-.918c-2.833-5.479-7.584-8.088-12.281-7.446a1 1 0 0 0 .271 1.982Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.293 2.293a1 1 0 0 1 1.414 0L7.335 5.92l.03.03 3.22 3.222 4.243 4.242 3.22 3.22.03.03 3.63 3.629a1 1 0 0 1-1.415 1.414l-3.09-3.09c-2.65 1.478-5.625 1.778-8.421.869-3.039-.987-5.779-3.37-7.67-7.027a1 1 0 0 1 0-.918c1.086-2.1 2.452-3.78 3.996-5.019L2.293 3.707a1 1 0 0 1 0-1.414Zm4.24 5.654 2.021 2.021a4 4 0 0 0 5.478 5.478l1.688 1.688c-2.042.982-4.246 1.124-6.32.45-2.34-.76-4.594-2.586-6.265-5.584.97-1.739 2.135-3.083 3.398-4.053Zm3.535 3.535 2.45 2.45a2 2 0 0 1-2.45-2.45Zm.81-5.405c3.573-.49 7.45 1.369 9.987 5.923a15 15 0 0 1-1.347 2.02 1 1 0 1 0 1.564 1.247 17 17 0 0 0 1.806-2.808 1 1 0 0 0 0-.918c-2.833-5.479-7.584-8.088-12.281-7.446a1 1 0 0 0 .271 1.982Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 825 B After Width: | Height: | Size: 809 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3.135 12C5.413 16.088 8.77 18 12 18s6.587-1.912 8.865-6C18.587 7.912 15.23 6 12 6c-3.228 0-6.587 1.912-8.865 6ZM12 4c4.24 0 8.339 2.611 10.888 7.54a1 1 0 0 1 0 .92C20.338 17.388 16.24 20 12 20c-4.24 0-8.339-2.611-10.888-7.54a1 1 0 0 1 0-.92C3.662 6.612 7.76 4 12 4Zm0 6a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-4 2a4 4 0 1 1 8 0 4 4 0 0 1-8 0Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3.135 12C5.413 16.088 8.77 18 12 18s6.587-1.912 8.865-6C18.587 7.912 15.23 6 12 6c-3.228 0-6.587 1.912-8.865 6ZM12 4c4.24 0 8.339 2.611 10.888 7.54a1 1 0 0 1 0 .92C20.338 17.388 16.24 20 12 20s-8.339-2.611-10.888-7.54a1 1 0 0 1 0-.92C3.662 6.612 7.76 4 12 4Zm0 6a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-4 2a4 4 0 1 1 8 0 4 4 0 0 1-8 0Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 476 B After Width: | Height: | Size: 469 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4Zm1 16V5h14v14H5Zm10.725-5.2c0 .566-.283.872-.802.872-.538 0-.848-.318-.848-.872v-3.635c0-.512.314-.826.82-.826h2.496c.35 0 .609.272.609.64 0 .369-.26.629-.609.629h-1.666v.973h1.47c.365 0 .608.248.608.613 0 .36-.247.613-.608.613h-1.47v.993Zm-3.367.872c.526 0 .813-.31.813-.872v-3.627c0-.558-.295-.873-.825-.873s-.825.31-.825.873V13.8c0 .558.302.872.837.872Zm-3.879.078C6.92 14.75 6 13.827 6 12.287v-.617c0-1.47.955-2.42 2.472-2.42.589 0 1.139.147 1.548.388.404.236.664.562.664.915 0 .373-.271.636-.656.636a.82.82 0 0 1-.41-.108 2.34 2.34 0 0 1-.271-.177c-.208-.148-.421-.3-.746-.3-.644 0-.95.38-.95 1.155v.52c0 .768.306 1.168.903 1.168.436 0 .735-.248.735-.61v-.061h-.146c-.412 0-.632-.194-.632-.551 0-.353.216-.535.632-.535h.806c.617 0 .884.256.884.834v.166c0 1.253-.92 2.06-2.354 2.06Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4Zm1 16V5h14v14H5Zm10.725-5.2c0 .566-.283.872-.802.872-.538 0-.848-.318-.848-.872v-3.635c0-.512.314-.826.82-.826h2.496c.35 0 .609.272.609.64 0 .369-.26.629-.609.629h-1.666v.973h1.47c.365 0 .608.248.608.613 0 .36-.247.613-.608.613h-1.47v.993Zm-3.367.872c.526 0 .813-.31.813-.872v-3.627c0-.558-.295-.873-.825-.873s-.825.31-.825.873V13.8c0 .558.302.872.837.872Zm-3.879.078C6.92 14.75 6 13.827 6 12.287v-.617c0-1.47.955-2.42 2.472-2.42.589 0 1.139.147 1.548.388.404.236.664.562.664.915 0 .373-.271.636-.656.636a.8.8 0 0 1-.41-.108 2 2 0 0 1-.271-.177c-.208-.148-.421-.3-.746-.3-.644 0-.95.38-.95 1.155v.52c0 .768.306 1.168.903 1.168.436 0 .735-.248.735-.61v-.061h-.146c-.412 0-.632-.194-.632-.551 0-.353.216-.535.632-.535h.806c.617 0 .884.256.884.834v.166c0 1.253-.92 2.06-2.354 2.06Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1000 B After Width: | Height: | Size: 992 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H3Zm1 14V6h16v12H4Zm2-5.713c0 1.54.92 2.463 2.48 2.463 1.434 0 2.353-.807 2.353-2.06v-.166c0-.578-.267-.834-.884-.834h-.806c-.416 0-.632.182-.632.535 0 .357.22.55.632.55h.146v.063c0 .36-.299.609-.735.609-.597 0-.904-.4-.904-1.168v-.52c0-.775.307-1.155.951-1.155.325 0 .538.152.746.3.089.064.176.127.272.177a.82.82 0 0 0 .409.108c.385 0 .656-.263.656-.636 0-.353-.26-.679-.664-.915-.409-.24-.96-.388-1.548-.388C6.955 9.25 6 10.2 6 11.67v.617Zm6.358 2.385c.526 0 .813-.31.813-.872v-3.627c0-.558-.295-.873-.825-.873s-.825.31-.825.873V13.8c0 .558.302.872.837.872Zm3.367-.872c0 .566-.283.872-.802.872-.538 0-.848-.318-.848-.872v-3.635c0-.512.314-.826.82-.826h2.496c.35 0 .609.272.609.64 0 .369-.26.629-.609.629h-1.666v.973h1.47c.365 0 .608.248.608.613 0 .36-.247.613-.608.613h-1.47v.993Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H3Zm1 14V6h16v12H4Zm2-5.713c0 1.54.92 2.463 2.48 2.463 1.434 0 2.353-.807 2.353-2.06v-.166c0-.578-.267-.834-.884-.834h-.806c-.416 0-.632.182-.632.535 0 .357.22.55.632.55h.146v.063c0 .36-.299.609-.735.609-.597 0-.904-.4-.904-1.168v-.52c0-.775.307-1.155.951-1.155.325 0 .538.152.746.3.089.064.176.127.272.177a.8.8 0 0 0 .409.108c.385 0 .656-.263.656-.636 0-.353-.26-.679-.664-.915-.409-.24-.96-.388-1.548-.388C6.955 9.25 6 10.2 6 11.67v.617Zm6.358 2.385c.526 0 .813-.31.813-.872v-3.627c0-.558-.295-.873-.825-.873s-.825.31-.825.873V13.8c0 .558.302.872.837.872Zm3.367-.872c0 .566-.283.872-.802.872-.538 0-.848-.318-.848-.872v-3.635c0-.512.314-.826.82-.826h2.496c.35 0 .609.272.609.64 0 .369-.26.629-.609.629h-1.666v.973h1.47c.365 0 .608.248.608.613 0 .36-.247.613-.608.613h-1.47v.993Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 993 B After Width: | Height: | Size: 991 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.062 11h2.961c.103-2.204.545-4.218 1.235-5.77.06-.136.123-.269.188-.399A8.007 8.007 0 0 0 4.062 11ZM12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm0 2c-.227 0-.518.1-.868.432-.354.337-.719.872-1.047 1.61-.561 1.263-.958 2.991-1.06 4.958h5.95c-.102-1.967-.499-3.695-1.06-4.958-.328-.738-.693-1.273-1.047-1.61C12.518 4.099 12.227 4 12 4Zm4.977 7c-.103-2.204-.545-4.218-1.235-5.77a9.78 9.78 0 0 0-.188-.399A8.006 8.006 0 0 1 19.938 11h-2.961Zm-2.003 2H9.026c.101 1.966.498 3.695 1.06 4.958.327.738.692 1.273 1.046 1.61.35.333.641.432.868.432.227 0 .518-.1.868-.432.354-.337.719-.872 1.047-1.61.561-1.263.958-2.991 1.06-4.958Zm.58 6.169c.065-.13.128-.263.188-.399.69-1.552 1.132-3.566 1.235-5.77h2.961a8.006 8.006 0 0 1-4.384 6.169Zm-7.108 0a9.877 9.877 0 0 1-.188-.399c-.69-1.552-1.132-3.566-1.235-5.77H4.062a8.006 8.006 0 0 0 4.384 6.169Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4.062 11h2.961c.103-2.204.545-4.218 1.235-5.77a9 9 0 0 1 .188-.399A8 8 0 0 0 4.062 11ZM12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm0 2c-.227 0-.518.1-.868.432-.354.337-.719.872-1.047 1.61-.561 1.263-.958 2.991-1.06 4.958h5.95c-.102-1.967-.499-3.695-1.06-4.958-.328-.738-.693-1.273-1.047-1.61C12.518 4.099 12.227 4 12 4Zm4.977 7c-.103-2.204-.545-4.218-1.235-5.77a10 10 0 0 0-.188-.399A8 8 0 0 1 19.938 11h-2.961Zm-2.003 2H9.026c.101 1.966.498 3.695 1.06 4.958.327.738.692 1.273 1.046 1.61.35.333.641.432.868.432s.518-.1.868-.432c.354-.337.719-.872 1.047-1.61.561-1.263.958-2.991 1.06-4.958Zm.58 6.169a9 9 0 0 0 .188-.399c.69-1.552 1.132-3.566 1.235-5.77h2.961a8 8 0 0 1-4.384 6.169Zm-7.108 0a10 10 0 0 1-.188-.399c-.69-1.552-1.132-3.566-1.235-5.77H4.062a8 8 0 0 0 4.384 6.169Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1005 B After Width: | Height: | Size: 946 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M8 5a2 2 0 1 0 0 4 2 2 0 0 0 0-4ZM4 7a4 4 0 1 1 8 0 4 4 0 0 1-8 0Zm13-1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Zm-3.5 1.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0Zm5.826 7.376c-.919-.779-2.052-1.03-3.1-.787a1 1 0 0 1-.451-1.949c1.671-.386 3.45.028 4.844 1.211 1.397 1.185 2.348 3.084 2.524 5.579a1 1 0 0 1-.997 1.07H18a1 1 0 1 1 0-2h3.007c-.29-1.47-.935-2.49-1.681-3.124ZM3.126 19h9.747c-.61-3.495-2.867-5-4.873-5-2.006 0-4.263 1.505-4.873 5ZM8 12c3.47 0 6.64 2.857 6.998 7.93A1 1 0 0 1 14 21H2a1 1 0 0 1-.998-1.07C1.36 14.857 4.53 12 8 12Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M8 5a2 2 0 1 0 0 4 2 2 0 0 0 0-4ZM4 7a4 4 0 1 1 8 0 4 4 0 0 1-8 0Zm13-1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Zm-3.5 1.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0Zm5.826 7.376c-.919-.779-2.052-1.03-3.1-.787a1 1 0 0 1-.451-1.949c1.671-.386 3.45.028 4.844 1.211 1.397 1.185 2.348 3.084 2.524 5.579a1 1 0 0 1-.997 1.07H18a1 1 0 1 1 0-2h3.007c-.29-1.47-.935-2.49-1.681-3.124ZM3.126 19h9.747c-.61-3.495-2.867-5-4.873-5s-4.263 1.505-4.873 5ZM8 12c3.47 0 6.64 2.857 6.998 7.93A1 1 0 0 1 14 21H2a1 1 0 0 1-.998-1.07C1.36 14.857 4.53 12 8 12Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 674 B After Width: | Height: | Size: 667 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3 4a1 1 0 0 1 1-1h1a8.003 8.003 0 0 1 7.75 6.006A7.985 7.985 0 0 1 19 6h1a1 1 0 0 1 1 1v1a8 8 0 0 1-8 8v4a1 1 0 1 1-2 0v-7a8 8 0 0 1-8-8V4Zm2 1a6 6 0 0 1 6 6 6 6 0 0 1-6-6Zm8 9a6 6 0 0 1 6-6 6 6 0 0 1-6 6Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3 4a1 1 0 0 1 1-1h1a8 8 0 0 1 7.75 6.006A7.99 7.99 0 0 1 19 6h1a1 1 0 0 1 1 1v1a8 8 0 0 1-8 8v4a1 1 0 1 1-2 0v-7a8 8 0 0 1-8-8V4Zm2 1a6 6 0 0 1 6 6 6 6 0 0 1-6-6Zm8 9a6 6 0 0 1 6-6 6 6 0 0 1-6 6Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 349 B After Width: | Height: | Size: 339 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M13.5 4a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM10 5a1 1 0 1 0 0-2 1 1 0 0 0 0 2ZM8 6a1 1 0 0 0 0 2v2.64c-.212.25-.45.515-.711.8l-.129.142c-.312.342-.649.711-.974 1.092-.731.857-1.488 1.866-1.89 2.99A4.845 4.845 0 0 0 4 17.297 4.702 4.702 0 0 0 8.702 22h6.596A4.702 4.702 0 0 0 20 17.298c0-.575-.114-1.122-.297-1.634-.401-1.124-1.157-2.133-1.89-2.99-.324-.38-.66-.75-.973-1.092l-.129-.141c-.26-.286-.5-.55-.711-.8V8a1 1 0 1 0 0-2H8Zm2 5.35V8h4v3.35l.22.275c.306.383.661.777 1.013 1.163l.13.143c.315.345.628.688.93 1.042.372.435.704.861.974 1.28l-.159.025c-.845.13-1.838.242-2.581.222-.842-.022-1.475-.217-2.227-.454l-.027-.008c-.746-.235-1.61-.507-2.746-.538-.743-.02-1.617.064-2.38.165.173-.228.36-.459.56-.692.302-.354.615-.697.93-1.042l.13-.143c.352-.386.707-.78 1.014-1.163L10 11.35Zm7.41 5.905c.21-.032.407-.064.586-.095A2.702 2.702 0 0 1 15.298 20H8.702A2.702 2.702 0 0 1 6 17.298c0-.142.013-.286.039-.434.236-.043.53-.093.853-.142.845-.13 1.837-.242 2.581-.222.842.022 1.475.217 2.227.454l.027.008c.746.235 1.61.507 2.746.538.931.024 2.07-.113 2.937-.245Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M13.5 4a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM10 5a1 1 0 1 0 0-2 1 1 0 0 0 0 2ZM8 6a1 1 0 0 0 0 2v2.64q-.319.374-.711.8l-.129.142c-.312.342-.649.711-.974 1.092-.731.857-1.488 1.866-1.89 2.99A4.9 4.9 0 0 0 4 17.297 4.7 4.7 0 0 0 8.702 22h6.596A4.7 4.7 0 0 0 20 17.298a4.8 4.8 0 0 0-.297-1.634c-.401-1.124-1.157-2.133-1.89-2.99-.324-.38-.66-.75-.973-1.092l-.129-.141c-.26-.286-.5-.55-.711-.8V8a1 1 0 1 0 0-2H8Zm2 5.35V8h4v3.35l.22.275c.306.383.661.777 1.013 1.163l.13.143c.315.345.628.688.93 1.042.372.435.704.861.974 1.28l-.159.025c-.845.13-1.838.242-2.581.222-.842-.022-1.475-.217-2.227-.454l-.027-.008c-.746-.235-1.61-.507-2.746-.538-.743-.02-1.617.064-2.38.165q.26-.342.56-.692c.302-.354.615-.697.93-1.042l.13-.143c.352-.386.707-.78 1.014-1.163L10 11.35Zm7.41 5.905q.316-.048.586-.095A2.7 2.7 0 0 1 15.298 20H8.702A2.7 2.7 0 0 1 6 17.298a2.5 2.5 0 0 1 .039-.434c.236-.043.53-.093.853-.142.845-.13 1.837-.242 2.581-.222.842.022 1.475.217 2.227.454l.027.008c.746.235 1.61.507 2.746.538.931.024 2.07-.113 2.937-.245Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3 4a1 1 0 0 1 1-1h1a8.003 8.003 0 0 1 7.75 6.006A7.985 7.985 0 0 1 19 6h1a1 1 0 0 1 1 1v1a8 8 0 0 1-8 8v4a1 1 0 1 1-2 0v-7a8 8 0 0 1-8-8V4Zm2 1a6 6 0 0 1 6 6 6 6 0 0 1-6-6Zm8 9a6 6 0 0 1 6-6 6 6 0 0 1-6 6Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M3 4a1 1 0 0 1 1-1h1a8 8 0 0 1 7.75 6.006A7.99 7.99 0 0 1 19 6h1a1 1 0 0 1 1 1v1a8 8 0 0 1-8 8v4a1 1 0 1 1-2 0v-7a8 8 0 0 1-8-8V4Zm2 1a6 6 0 0 1 6 6 6 6 0 0 1-6-6Zm8 9a6 6 0 0 1 6-6 6 6 0 0 1-6 6Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 348 B After Width: | Height: | Size: 339 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 12a8 8 0 1 1 4.445 7.169 1 1 0 0 0-.629-.088l-3.537.662.7-3.415a1 1 0 0 0-.09-.66A7.961 7.961 0 0 1 4 12Zm8-10C6.477 2 2 6.477 2 12c0 1.523.341 2.968.951 4.262l-.93 4.537a1 1 0 0 0 1.163 1.184l4.68-.876A9.968 9.968 0 0 0 12 22c5.523 0 10-4.477 10-10S17.523 2 12 2ZM7.5 13.25a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Zm4.5 0a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Zm4.5 0a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 12a8 8 0 1 1 4.445 7.169 1 1 0 0 0-.629-.088l-3.537.662.7-3.415a1 1 0 0 0-.09-.66A7.96 7.96 0 0 1 4 12Zm8-10C6.477 2 2 6.477 2 12a10 10 0 0 0 .951 4.262l-.93 4.537a1 1 0 0 0 1.163 1.184l4.68-.876A10 10 0 0 0 12 22c5.523 0 10-4.477 10-10S17.523 2 12 2ZM7.5 13.25a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Zm4.5 0a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Zm4.5 0a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 567 B After Width: | Height: | Size: 554 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10a9.968 9.968 0 0 1-4.136-.893l-4.68.876a1 1 0 0 1-1.164-1.184l.931-4.537A9.965 9.965 0 0 1 2 12Zm4.25 0a1.25 1.25 0 1 0 2.5 0 1.25 1.25 0 0 0-2.5 0Zm4.5 0a1.25 1.25 0 1 0 2.5 0 1.25 1.25 0 0 0-2.5 0Zm5.75 1.25a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10a10 10 0 0 1-4.136-.893l-4.68.876a1 1 0 0 1-1.164-1.184l.931-4.537A10 10 0 0 1 2 12Zm4.25 0a1.25 1.25 0 1 0 2.5 0 1.25 1.25 0 0 0-2.5 0Zm4.5 0a1.25 1.25 0 1 0 2.5 0 1.25 1.25 0 0 0-2.5 0Zm5.75 1.25a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 453 B After Width: | Height: | Size: 441 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M18.423 2.428a2 2 0 0 1 2.575 1.916V15.5c0 2.096-1.97 3.5-4 3.5-2.03 0-4-1.404-4-3.5s1.97-3.5 4-3.5c.7 0 1.392.167 2 .471V4.344l-8 2.4V18.5c0 2.096-1.97 3.5-4 3.5-2.03 0-4-1.404-4-3.5s1.97-3.5 4-3.5c.7 0 1.393.167 2 .471V6.744a2 2 0 0 1 1.425-1.916l8-2.4ZM8.998 18.5c0-.666-.717-1.5-2-1.5s-2 .834-2 1.5c0 .665.717 1.5 2 1.5s2-.835 2-1.5Zm10-3c0-.665-.717-1.5-2-1.5s-2 .835-2 1.5.717 1.5 2 1.5 2-.835 2-1.5Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M18.423 2.428a2 2 0 0 1 2.575 1.916V15.5c0 2.096-1.97 3.5-4 3.5s-4-1.404-4-3.5 1.97-3.5 4-3.5c.7 0 1.392.167 2 .471V4.344l-8 2.4V18.5c0 2.096-1.97 3.5-4 3.5s-4-1.404-4-3.5 1.97-3.5 4-3.5c.7 0 1.393.167 2 .471V6.744a2 2 0 0 1 1.425-1.916l8-2.4ZM8.998 18.5c0-.666-.717-1.5-2-1.5s-2 .834-2 1.5c0 .665.717 1.5 2 1.5s2-.835 2-1.5Zm10-3c0-.665-.717-1.5-2-1.5s-2 .835-2 1.5.717 1.5 2 1.5 2-.835 2-1.5Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 548 B After Width: | Height: | Size: 537 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M20.707 3.293a1 1 0 0 1 0 1.414l-16 16a1 1 0 0 1-1.414-1.414l2.616-2.616A1.998 1.998 0 0 1 5 15V9a2 2 0 0 1 2-2h2.697l5.748-3.832A1 1 0 0 1 17 4v1.586l2.293-2.293a1 1 0 0 1 1.414 0ZM15 7.586 7.586 15H7V9h2.697a2 2 0 0 0 1.11-.336L15 5.87v1.717Zm2 3.657-2 2v4.888l-2.933-1.955-1.442 1.442 4.82 3.214A1 1 0 0 0 17 20v-8.757Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M20.707 3.293a1 1 0 0 1 0 1.414l-16 16a1 1 0 0 1-1.414-1.414l2.616-2.616A2 2 0 0 1 5 15V9a2 2 0 0 1 2-2h2.697l5.748-3.832A1 1 0 0 1 17 4v1.586l2.293-2.293a1 1 0 0 1 1.414 0ZM15 7.586 7.586 15H7V9h2.697a2 2 0 0 0 1.11-.336L15 5.87v1.717Zm2 3.657-2 2v4.888l-2.933-1.955-1.442 1.442 4.82 3.214A1 1 0 0 0 17 20v-8.757Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 465 B After Width: | Height: | Size: 457 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M1 5a1 1 0 0 1 1-1h7a3.99 3.99 0 0 1 3 1.354A3.99 3.99 0 0 1 15 4h7a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-6.723c-.52 0-1 .125-1.4.372-.421.26-.761.633-.983 1.075a1 1 0 0 1-1.788 0 2.664 2.664 0 0 0-.983-1.075c-.4-.247-.88-.372-1.4-.372H2a1 1 0 0 1-1-1V5Zm10 3a2 2 0 0 0-2-2H3v12h5.723c.776 0 1.564.173 2.277.569V8Zm2 10.569V8a2 2 0 0 1 2-2h6v12h-5.723c-.776 0-1.564.173-2.277.569Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M1 5a1 1 0 0 1 1-1h7a4 4 0 0 1 3 1.354A4 4 0 0 1 15 4h7a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-6.723c-.52 0-1 .125-1.4.372-.421.26-.761.633-.983 1.075a1 1 0 0 1-1.788 0 2.66 2.66 0 0 0-.983-1.075c-.4-.247-.88-.372-1.4-.372H2a1 1 0 0 1-1-1V5Zm10 3a2 2 0 0 0-2-2H3v12h5.723c.776 0 1.564.173 2.277.569V8Zm2 10.569V8a2 2 0 0 1 2-2h6v12h-5.723c-.776 0-1.564.173-2.277.569Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 517 B After Width: | Height: | Size: 503 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#FFC404" fill-rule="evenodd" d="M11.183 8.561c0 .544.348.984.892.984.545 0 .893-.44.893-.985V6.985c0-.544-.348-.985-.893-.985-.543 0-.892.44-.892.985v1.576Zm5.94 7.481c0 .539-.438.942-.976.942H8.004c-.538 0-.975-.411-.975-.95 0-2.782 2.264-5.021 5.046-5.021 2.783 0 5.047 2.247 5.047 5.03Zm-.43-4.584a.983.983 0 0 1 0-1.393l1.114-1.114a.985.985 0 0 1 1.393 1.393l-1.114 1.114a.985.985 0 0 1-1.393 0Zm2.897 3.741h1.575c.544 0 .985.349.985.892 0 .544-.44.892-.985.892h-1.67a.872.872 0 0 1-.89-.887c0-.543.44-.897.985-.897Zm-14.045.893c0-.544-.44-.892-.985-.892H2.985c-.544 0-.985.349-.985.892 0 .544.44.892.985.892H4.56c.545 0 .985-.349.985-.892Zm1.913-6.027a.985.985 0 0 1-1.393 1.393L4.95 10.344A.985.985 0 0 1 6.344 8.95l1.114 1.114Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#FFC404" fill-rule="evenodd" d="M11.183 8.561c0 .544.348.984.892.984.545 0 .893-.44.893-.985V6.985c0-.544-.348-.985-.893-.985-.543 0-.892.44-.892.985v1.576Zm5.94 7.481c0 .539-.438.942-.976.942H8.004c-.538 0-.975-.411-.975-.95 0-2.782 2.264-5.021 5.046-5.021s5.047 2.247 5.047 5.03Zm-.43-4.584a.983.983 0 0 1 0-1.393l1.114-1.114a.985.985 0 0 1 1.393 1.393l-1.114 1.114a.985.985 0 0 1-1.393 0Zm2.897 3.741h1.575c.544 0 .985.349.985.892 0 .544-.44.892-.985.892h-1.67a.87.87 0 0 1-.89-.887c0-.543.44-.897.985-.897Zm-14.045.893c0-.544-.44-.892-.985-.892H2.985c-.544 0-.985.349-.985.892 0 .544.44.892.985.892H4.56c.545 0 .985-.349.985-.892Zm1.913-6.027a.985.985 0 0 1-1.393 1.393L4.95 10.344A.985.985 0 0 1 6.344 8.95l1.114 1.114Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 848 B After Width: | Height: | Size: 838 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M8.004 5a1 1 0 0 0-.43-.822c-.57-.395-1.176-.031-1.685.255-.428.24-.998.614-1.569 1.15C3.166 6.665 2.004 8.415 2.004 11v8a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-2V5ZM19.004 5a1 1 0 0 0-.43-.822c-.57-.395-1.176-.031-1.685.255-.428.24-.998.614-1.569 1.15-1.154 1.082-2.316 2.832-2.316 5.417v8a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-2V5Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M8.004 5a1 1 0 0 0-.43-.822c-.57-.395-1.176-.031-1.685.255-.428.24-.998.614-1.569 1.15C3.166 6.665 2.004 8.415 2.004 11v8a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-2V5Zm11 0a1 1 0 0 0-.43-.822c-.57-.395-1.176-.031-1.685.255-.428.24-.998.614-1.569 1.15-1.154 1.082-2.316 2.832-2.316 5.417v8a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-2V5Z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 455 B After Width: | Height: | Size: 451 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7.574 4.178a1 1 0 0 1 .43.822v5h2a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-8c0-2.585 1.162-4.335 2.316-5.417a8.163 8.163 0 0 1 1.569-1.15 7.029 7.029 0 0 1 .738-.36l.016-.005.005-.003h.003v-.001c.001 0 .002 0 .353.936l-.351-.936a1 1 0 0 1 .92.114Zm-1.57 2.588a5.99 5.99 0 0 0-.316.276C4.842 7.835 4.004 9.085 4.004 11v7h5v-6h-2a1 1 0 0 1-1-1V6.766Zm12.57-2.588a1 1 0 0 1 .43.822v5h2a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-8c0-2.585 1.162-4.335 2.316-5.417a8.166 8.166 0 0 1 1.569-1.15 7.038 7.038 0 0 1 .738-.36l.016-.005.005-.003h.003v-.001c.001 0 .002 0 .353.936l-.351-.936a1 1 0 0 1 .92.114Zm-1.57 2.588c-.105.085-.21.177-.316.276-.846.793-1.684 2.043-1.684 3.958v7h5v-6h-2a1 1 0 0 1-1-1V6.766Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7.574 4.178a1 1 0 0 1 .43.822v5h2a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-8c0-2.585 1.162-4.335 2.316-5.417a8.2 8.2 0 0 1 1.569-1.15 7 7 0 0 1 .738-.36l.016-.005.005-.003h.003v-.001c.001 0 .002 0 .353.936l-.351-.936a1 1 0 0 1 .92.114Zm-1.57 2.588a6 6 0 0 0-.316.276C4.842 7.835 4.004 9.085 4.004 11v7h5v-6h-2a1 1 0 0 1-1-1V6.766Zm12.57-2.588a1 1 0 0 1 .43.822v5h2a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-8c0-2.585 1.162-4.335 2.316-5.417a8.2 8.2 0 0 1 1.569-1.15 7 7 0 0 1 .738-.36l.016-.005.005-.003h.003v-.001c.001 0 .002 0 .353.936l-.351-.936a1 1 0 0 1 .92.114Zm-1.57 2.588q-.157.128-.316.276c-.846.793-1.684 2.043-1.684 3.958v7h5v-6h-2a1 1 0 0 1-1-1V6.766Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 820 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4 4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4ZM14 4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V4Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M4 4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4Zm10 0a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V4Z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 245 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4 6a3 3 0 0 1 6 0v12a3 3 0 1 1-6 0V6ZM14 6a3 3 0 1 1 6 0v12a3 3 0 1 1-6 0V6Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M4 6a3 3 0 0 1 6 0v12a3 3 0 1 1-6 0V6Zm10 0a3 3 0 1 1 6 0v12a3 3 0 1 1-6 0V6Z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 180 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4Zm2 1v14h2V5H6Zm8-1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V4Zm2 1v14h2V5h-2Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4Zm2 1v14h2V5H6Zm8-1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V4Zm2 1v14h2V5h-2Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 313 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 6a3 3 0 0 1 6 0v12a3 3 0 1 1-6 0V6Zm3-1a1 1 0 0 0-1 1v12a1 1 0 1 0 2 0V6a1 1 0 0 0-1-1Zm7 1a3 3 0 1 1 6 0v12a3 3 0 1 1-6 0V6Zm3-1a1 1 0 0 0-1 1v12a1 1 0 1 0 2 0V6a1 1 0 0 0-1-1Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M4 6a3 3 0 0 1 6 0v12a3 3 0 1 1-6 0V6Zm3-1a1 1 0 0 0-1 1v12a1 1 0 1 0 2 0V6a1 1 0 0 0-1-1Zm7 1a3 3 0 1 1 6 0v12a3 3 0 1 1-6 0V6Zm3-1a1 1 0 0 0-1 1v12a1 1 0 1 0 2 0V6a1 1 0 0 0-1-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 323 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M10 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM5.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM16 11a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2h-5a1 1 0 0 1-1-1ZM3.678 19h12.644c-.71-2.909-3.092-5-6.322-5s-5.613 2.091-6.322 5Zm-2.174.906C1.917 15.521 5.242 12 10 12c4.758 0 8.083 3.521 8.496 7.906A1 1 0 0 1 17.5 21h-15a1 1 0 0 1-.996-1.094Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M10 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM5.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM16 11a1 1 0 0 1 1-1h5a1 1 0 1 1 0 2h-5a1 1 0 0 1-1-1ZM3.678 19h12.644c-.71-2.909-3.092-5-6.322-5s-5.613 2.091-6.322 5Zm-2.174.906C1.917 15.521 5.242 12 10 12s8.083 3.521 8.496 7.906A1 1 0 0 1 17.5 21h-15a1 1 0 0 1-.996-1.094Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 463 B After Width: | Height: | Size: 456 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.679 19c.709-2.902 3.079-5 6.321-5a6.69 6.69 0 0 1 2.612.51 1 1 0 0 0 .776-1.844A8.687 8.687 0 0 0 12 12c-4.3 0-7.447 2.884-8.304 6.696-.29 1.29.767 2.304 1.902 2.304H11a1 1 0 1 0 0-2H5.679Zm14.835-4.857a1 1 0 0 1 .344 1.371l-3 5a1 1 0 0 1-1.458.286l-2-1.5a1 1 0 0 1 1.2-1.6l1.113.835 2.43-4.05a1 1 0 0 1 1.372-.342Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.679 19c.709-2.902 3.079-5 6.321-5a6.7 6.7 0 0 1 2.612.51 1 1 0 0 0 .776-1.844A8.7 8.7 0 0 0 12 12c-4.3 0-7.447 2.884-8.304 6.696-.29 1.29.767 2.304 1.902 2.304H11a1 1 0 1 0 0-2H5.679Zm14.835-4.857a1 1 0 0 1 .344 1.371l-3 5a1 1 0 0 1-1.458.286l-2-1.5a1 1 0 0 1 1.2-1.6l1.113.835 2.43-4.05a1 1 0 0 1 1.372-.342Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 542 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.678 19c.71-2.909 3.092-5 6.322-5 .621 0 1.206.077 1.748.218a1 1 0 1 0 .504-1.936A8.931 8.931 0 0 0 12 12c-4.758 0-8.083 3.521-8.496 7.906A1 1 0 0 0 4.5 21H11a1 1 0 1 0 0-2H5.678ZM18 14a1 1 0 0 1 1 1v2h2a1 1 0 1 1 0 2h-2v2a1 1 0 1 1-2 0v-2h-2a1 1 0 1 1 0-2h2v-2a1 1 0 0 1 1-1Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.678 19c.71-2.909 3.092-5 6.322-5 .621 0 1.206.077 1.748.218a1 1 0 1 0 .504-1.936A9 9 0 0 0 12 12c-4.758 0-8.083 3.521-8.496 7.906A1 1 0 0 0 4.5 21H11a1 1 0 1 0 0-2H5.678ZM18 14a1 1 0 0 1 1 1v2h2a1 1 0 1 1 0 2h-2v2a1 1 0 1 1-2 0v-2h-2a1 1 0 1 1 0-2h2v-2a1 1 0 0 1 1-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 500 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.679 19c.709-2.902 3.079-5 6.321-5 .302 0 .595.018.878.053a1 1 0 0 0 .243-1.985A9.235 9.235 0 0 0 12 12c-4.3 0-7.447 2.884-8.304 6.696-.29 1.29.767 2.304 1.902 2.304H12a1 1 0 1 0 0-2H5.679Zm9.614-3.707a1 1 0 0 1 1.414 0L18 16.586l1.293-1.293a1 1 0 0 1 1.414 1.414L19.414 18l1.293 1.293a1 1 0 0 1-1.414 1.414L18 19.414l-1.293 1.293a1 1 0 0 1-1.414-1.414L16.586 18l-1.293-1.293a1 1 0 0 1 0-1.414Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.679 19c.709-2.902 3.079-5 6.321-5q.453 0 .878.053a1 1 0 0 0 .243-1.985A9 9 0 0 0 12 12c-4.3 0-7.447 2.884-8.304 6.696-.29 1.29.767 2.304 1.902 2.304H12a1 1 0 1 0 0-2H5.679Zm9.614-3.707a1 1 0 0 1 1.414 0L18 16.586l1.293-1.293a1 1 0 0 1 1.414 1.414L19.414 18l1.293 1.293a1 1 0 0 1-1.414 1.414L18 19.414l-1.293 1.293a1 1 0 0 1-1.414-1.414L16.586 18l-1.293-1.293a1 1 0 0 1 0-1.414Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 625 B After Width: | Height: | Size: 610 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.678 19h12.644c-.71-2.909-3.092-5-6.322-5s-5.613 2.091-6.322 5Zm-2.174.906C3.917 15.521 7.242 12 12 12c4.758 0 8.083 3.521 8.496 7.906A1 1 0 0 1 19.5 21h-15a1 1 0 0 1-.996-1.094Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5ZM7.5 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM5.678 19h12.644c-.71-2.909-3.092-5-6.322-5s-5.613 2.091-6.322 5Zm-2.174.906C3.917 15.521 7.242 12 12 12s8.083 3.521 8.496 7.906A1 1 0 0 1 19.5 21h-15a1 1 0 0 1-.996-1.094Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 410 B After Width: | Height: | Size: 402 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6.5 4.999Zm0 0a.054.054 0 0 1-.016.024.196.196 0 0 1-.152.043c.057.01.113.02.168.032V7.5a1 1 0 0 1-.33.742c-.543.49-.917 1.176-1.23 2.036a1 1 0 0 1-.94.657H3V14h1a1 1 0 0 1 .866.5c.436.754.879 1.195 1.637 1.636A1 1 0 0 1 7 17v2h2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2h2v-2.537a1 1 0 0 1 .332-.744A4.978 4.978 0 0 0 19 11.999 5 5 0 0 0 14 7H9.474a1 1 0 0 1-.893-.55v-.001l-.001-.002-.005-.008L9.474 6l-.9.438h.001v.002l.002.001.001.003.002.003v.003a2.62 2.62 0 0 0-.443-.538c-.319-.298-.839-.648-1.637-.814V5Zm2.082 1.452ZM9.5 4.447c.211.196.379.387.508.553H14a7 7 0 0 1 6.72 8.96 1.003 1.003 0 0 0 1.146-1.46 1 1 0 1 1 1.731-1 3 3 0 0 1-3.714 4.286A7.074 7.074 0 0 1 19 16.888V19a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2h-2a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-1.45A5.783 5.783 0 0 1 3.448 16H3a2 2 0 0 1-2-2v-3.065a2 2 0 0 1 2-2h.324c.286-.649.657-1.291 1.176-1.852V5c0-1.047.89-2.12 2.161-1.907 1.33.223 2.248.805 2.839 1.354ZM8.25 12a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6.5 4.999Zm0 0a.1.1 0 0 1-.016.024.2.2 0 0 1-.152.043q.086.014.168.032V7.5a1 1 0 0 1-.33.742c-.543.49-.917 1.176-1.23 2.036a1 1 0 0 1-.94.657H3V14h1a1 1 0 0 1 .866.5c.436.754.879 1.195 1.637 1.636A1 1 0 0 1 7 17v2h2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2h2v-2.537a1 1 0 0 1 .332-.744A4.98 4.98 0 0 0 19 11.999 5 5 0 0 0 14 7H9.474a1 1 0 0 1-.893-.55v-.001l-.001-.002-.005-.008L9.474 6l-.9.438h.001v.002l.002.001.001.003.002.003v.003a2.6 2.6 0 0 0-.443-.538c-.319-.298-.839-.648-1.637-.814V5Zm2.082 1.452ZM9.5 4.447c.211.196.379.387.508.553H14a7 7 0 0 1 6.72 8.96 1.003 1.003 0 0 0 1.146-1.46 1 1 0 1 1 1.731-1 3 3 0 0 1-3.714 4.286A7 7 0 0 1 19 16.888V19a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2h-2a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-1.45A5.8 5.8 0 0 1 3.448 16H3a2 2 0 0 1-2-2v-3.065a2 2 0 0 1 2-2h.324c.286-.649.657-1.291 1.176-1.852V5c0-1.047.89-2.12 2.161-1.907 1.33.223 2.248.805 2.839 1.354ZM8.25 12a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M18.438 3.253a2 2 0 0 1 2.309 2.31L18.243 20.17c-.186 1.083-1.244 1.868-2.387 1.588a18.525 18.525 0 0 1-8.702-4.912 18.525 18.525 0 0 1-4.912-8.702C1.962 7 2.747 5.943 3.83 5.757l14.608-2.504Zm-1.474 2.282a3 3 0 0 1-5.914 1.014l-3.368.577a13.022 13.022 0 0 0 3.376 5.816c.35.35.713.675 1.09.976a4.002 4.002 0 0 1 5.571-2.53l1.056-6.164-1.81.311Zm.388 7.991a2 2 0 0 0-3.346 1.634c.916.504 1.879.89 2.868 1.158l.478-2.792Zm-.817 4.77a15 15 0 0 1-6.891-3.94 15.02 15.02 0 0 1-3.94-6.89l-1.505.257a16.525 16.525 0 0 0 4.369 7.709 16.525 16.525 0 0 0 7.709 4.37l.258-1.505ZM13.022 6.212a1 1 0 0 0 1.97-.338l-1.97.338Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M18.438 3.253a2 2 0 0 1 2.309 2.31L18.243 20.17c-.186 1.083-1.244 1.868-2.387 1.588a18.5 18.5 0 0 1-8.702-4.912 18.5 18.5 0 0 1-4.912-8.702C1.962 7 2.747 5.943 3.83 5.757l14.608-2.504Zm-1.474 2.282a3 3 0 0 1-5.914 1.014l-3.368.577a13 13 0 0 0 3.376 5.816q.525.525 1.09.976a4.002 4.002 0 0 1 5.571-2.53l1.056-6.164-1.81.311Zm.388 7.991a2 2 0 0 0-3.346 1.634 13 13 0 0 0 2.868 1.158l.478-2.792Zm-.817 4.77a15 15 0 0 1-6.891-3.94 15 15 0 0 1-3.94-6.89l-1.505.257a16.5 16.5 0 0 0 4.369 7.709 16.5 16.5 0 0 0 7.709 4.37l.258-1.505ZM13.022 6.212a1 1 0 0 0 1.97-.338l-1.97.338Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 754 B After Width: | Height: | Size: 713 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M6.514 2.143A1 1 0 0 0 5 3v18a1 1 0 0 0 1.514.858l15-9a1 1 0 0 0 0-1.716l-15-9Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M6.514 2.143A1 1 0 0 0 5 3v18a1 1 0 0 0 1.514.858l15-9a1 1 0 0 0 0-1.716l-15-9Z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 182 B |
@@ -1 +1 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.507 2.13a1 1 0 0 1 1.008.013l15 9a1 1 0 0 1 0 1.714l-15 9A1 1 0 0 1 5 21V3a1 1 0 0 1 .507-.87ZM7 4.766v14.468L19.056 12 7 4.766Z" fill="#000"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M5.507 2.13a1 1 0 0 1 1.008.013l15 9a1 1 0 0 1 0 1.714l-15 9A1 1 0 0 1 5 21V3a1 1 0 0 1 .507-.87ZM7 4.766v14.468L19.056 12 7 4.766Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 276 B After Width: | Height: | Size: 274 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4c0-1.012.894-2.187 2.237-1.846a5.002 5.002 0 0 1 3.218 7.119 4.001 4.001 0 0 1 2.345 4.976A3.501 3.501 0 0 1 18.5 21h-13a3.5 3.5 0 0 1-1.3-6.75 4 4 0 0 1 2.052-4.848A4 4 0 0 1 10 4h2.001Zm-4.187 7.009A2 2 0 0 0 6 13c0 .366.098.706.271 1H12a1 1 0 1 1 0 2H5.5a1.5 1.5 0 0 0 0 3h13a1.5 1.5 0 1 0 0-3H17a1 1 0 1 1 0-2h.729c.173-.294.271-.634.271-1a2 2 0 0 0-2-2h-2a1 1 0 1 1 0-2h1.236a3.002 3.002 0 0 0-1.243-4.832A2 2 0 0 1 12 6h-2a2 2 0 0 0-1.728 3.009H9a1 1 0 0 1 0 2H7.813Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4c0-1.012.894-2.187 2.237-1.846a5.002 5.002 0 0 1 3.218 7.119 4 4 0 0 1 2.345 4.976A3.501 3.501 0 0 1 18.5 21h-13a3.5 3.5 0 0 1-1.3-6.75 4 4 0 0 1 2.052-4.848A4 4 0 0 1 10 4h2.001Zm-4.187 7.009A2 2 0 0 0 6 13c0 .366.098.706.271 1H12a1 1 0 1 1 0 2H5.5a1.5 1.5 0 0 0 0 3h13a1.5 1.5 0 1 0 0-3H17a1 1 0 1 1 0-2h.729A1.96 1.96 0 0 0 18 13a2 2 0 0 0-2-2h-2a1 1 0 1 1 0-2h1.236a3.002 3.002 0 0 0-1.243-4.832A2 2 0 0 1 12 6h-2a2 2 0 0 0-1.728 3.009H9a1 1 0 0 1 0 2H7.813Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 620 B After Width: | Height: | Size: 610 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#080B12" fill-rule="evenodd" d="M3 5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm6 0H5v4h4V5ZM3 15a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4Zm6 0H5v4h4v-4ZM13 5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2V5Zm6 0h-4v4h4V5ZM14 13a1 1 0 0 1 1 1v1h1a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1Zm3 1a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1Zm0 4a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-1v1a1 1 0 1 1-2 0v-2Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#080B12" fill-rule="evenodd" d="M3 5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm6 0H5v4h4V5ZM3 15a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4Zm6 0H5v4h4v-4Zm4-10a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2V5Zm6 0h-4v4h4V5Zm-5 8a1 1 0 0 1 1 1v1h1a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1Zm3 1a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-2a1 1 0 0 1-1-1Zm0 4a1 1 0 0 1 1-1h2a1 1 0 1 1 0 2h-1v1a1 1 0 1 1-2 0v-2Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 580 B After Width: | Height: | Size: 579 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M10.25 4a.75.75 0 0 0-.75.75V11a1 1 0 1 1-2 0V6.75a.75.75 0 0 0-1.5 0V14a6 6 0 0 0 12 0V9a2 2 0 0 0-2 2v1.5a1 1 0 0 1-.684.949l-.628.21A2.469 2.469 0 0 0 13 16a1 1 0 1 1-2 0 4.469 4.469 0 0 1 3-4.22V11c0-.703.181-1.364.5-1.938V5.75a.75.75 0 0 0-1.5 0V9a1 1 0 1 1-2 0V4.75a.75.75 0 0 0-.75-.75Zm2.316-.733A2.75 2.75 0 0 1 16.5 5.75v1.54c.463-.187.97-.29 1.5-.29h1a1 1 0 0 1 1 1v6a8 8 0 1 1-16 0V6.75a2.75 2.75 0 0 1 3.571-2.625 2.751 2.751 0 0 1 4.995-.858Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M10.25 4a.75.75 0 0 0-.75.75V11a1 1 0 1 1-2 0V6.75a.75.75 0 0 0-1.5 0V14a6 6 0 0 0 12 0V9a2 2 0 0 0-2 2v1.5a1 1 0 0 1-.684.949l-.628.21A2.47 2.47 0 0 0 13 16a1 1 0 1 1-2 0 4.47 4.47 0 0 1 3-4.22V11c0-.703.181-1.364.5-1.938V5.75a.75.75 0 0 0-1.5 0V9a1 1 0 1 1-2 0V4.75a.75.75 0 0 0-.75-.75Zm2.316-.733A2.75 2.75 0 0 1 16.5 5.75v1.54A4 4 0 0 1 18 7h1a1 1 0 0 1 1 1v6a8 8 0 1 1-16 0V6.75a2.75 2.75 0 0 1 3.571-2.625 2.751 2.751 0 0 1 4.995-.858Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 585 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M10.75 2.469a2 2 0 0 1 2.5 0l1.42 1.136 1.44-.576A1.378 1.378 0 0 1 18 4.309V8a6.002 6.002 0 0 1-5 5.917v1.69a6.12 6.12 0 0 1 4.224-1.606A1.796 1.796 0 0 1 19 15.857a6.143 6.143 0 0 1-6 6.141V22h-2v-.002a6.143 6.143 0 0 1-6-6.222A1.796 1.796 0 0 1 6.858 14 6.12 6.12 0 0 1 11 15.607v-1.69A6.002 6.002 0 0 1 6 8V4.308c0-.975.985-1.641 1.89-1.28l1.44.577 1.42-1.136ZM7.004 16.003a4.143 4.143 0 0 1 3.995 3.994 4.143 4.143 0 0 1-3.995-3.994Zm9.994 0a4.143 4.143 0 0 1-3.995 3.994 4.143 4.143 0 0 1 3.995-3.994ZM13.42 5.167 12 4.03l-1.42 1.136a2 2 0 0 1-1.992.295L8 5.227V8a4 4 0 0 0 8 0V5.227l-.588.235a2 2 0 0 1-1.992-.295Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M10.75 2.469a2 2 0 0 1 2.5 0l1.42 1.136 1.44-.576A1.378 1.378 0 0 1 18 4.309V8a6 6 0 0 1-5 5.917v1.69a6.12 6.12 0 0 1 4.224-1.606A1.796 1.796 0 0 1 19 15.857a6.143 6.143 0 0 1-6 6.141V22h-2v-.002a6.143 6.143 0 0 1-6-6.222A1.796 1.796 0 0 1 6.858 14 6.12 6.12 0 0 1 11 15.607v-1.69A6 6 0 0 1 6 8V4.308c0-.975.985-1.641 1.89-1.28l1.44.577 1.42-1.136ZM7.004 16.003a4.143 4.143 0 0 1 3.995 3.994 4.143 4.143 0 0 1-3.995-3.994Zm9.994 0a4.143 4.143 0 0 1-3.995 3.994 4.143 4.143 0 0 1 3.995-3.994ZM13.42 5.167 12 4.03l-1.42 1.136a2 2 0 0 1-1.992.295L8 5.227V8a4 4 0 0 0 8 0V5.227l-.588.235a2 2 0 0 1-1.992-.295Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 763 B After Width: | Height: | Size: 748 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M9.996 2.869A1.951 1.951 0 0 1 11.62 2h.76c.653 0 1.262.326 1.624.869l1.141 1.712 1.749-.404a1.951 1.951 0 0 1 1.819.522l.588.589c.476.475.673 1.162.522 1.818l-.404 1.749 1.712 1.141c.543.362.869.971.869 1.624v.76c0 .653-.326 1.262-.869 1.624l-1.712 1.141.404 1.749a1.951 1.951 0 0 1-.522 1.819l-.588.588a1.951 1.951 0 0 1-1.819.522l-1.749-.404-1.141 1.712A1.951 1.951 0 0 1 12.38 22h-.76a1.951 1.951 0 0 1-1.624-.869L8.855 19.42l-1.749.404a1.951 1.951 0 0 1-1.818-.522l-.59-.588a1.951 1.951 0 0 1-.52-1.819l.403-1.749-1.712-1.141A1.951 1.951 0 0 1 2 12.38v-.76c0-.653.326-1.262.869-1.624L4.58 8.855l-.404-1.749A1.951 1.951 0 0 1 4.7 5.288l.589-.59a1.951 1.951 0 0 1 1.818-.52l1.749.403 1.141-1.712ZM8.5 12a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M9.996 2.869A1.95 1.95 0 0 1 11.62 2h.76c.653 0 1.262.326 1.624.869l1.141 1.712 1.749-.404a1.95 1.95 0 0 1 1.819.522l.588.589a1.95 1.95 0 0 1 .522 1.818l-.404 1.749 1.712 1.141c.543.362.869.971.869 1.624v.76c0 .653-.326 1.262-.869 1.624l-1.712 1.141.404 1.749a1.95 1.95 0 0 1-.522 1.819l-.588.588a1.95 1.95 0 0 1-1.819.522l-1.749-.404-1.141 1.712A1.95 1.95 0 0 1 12.38 22h-.76a1.95 1.95 0 0 1-1.624-.869L8.855 19.42l-1.749.404a1.95 1.95 0 0 1-1.818-.522l-.59-.588a1.95 1.95 0 0 1-.52-1.819l.403-1.749-1.712-1.141A1.95 1.95 0 0 1 2 12.38v-.76c0-.653.326-1.262.869-1.624L4.58 8.855l-.404-1.749A1.95 1.95 0 0 1 4.7 5.288l.589-.59a1.95 1.95 0 0 1 1.818-.52l1.749.403 1.141-1.712ZM8.5 12a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 886 B After Width: | Height: | Size: 862 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.275 4.312A1 1 0 0 1 3 4h.55a4 4 0 0 1 3.656 2.375l.616 1.388.47-.47 1.001-1a2.414 2.414 0 0 1 3.948.807 2.41 2.41 0 0 1 2.5 1.5 2.41 2.41 0 0 1 2.234 1.01l.805-.804c.95-.95 2.49-.95 3.44 0 .93.93.958 2.439.035 3.395-1.228 1.271-3.406 3.497-5.078 5.035a94.045 94.045 0 0 1-2.82 2.467c-2.481 2.1-6.156 1.748-8.264-.684L3.87 16.452a6 6 0 0 1-1.458-3.614l-.41-7.785a1 1 0 0 1 .274-.741Zm14.022 6.977-1.004 1.004-.007.006-.493.494a.414.414 0 1 1-.586-.586l1.5-1.5a.414.414 0 0 1 .59.582Zm-4.18 1.595a2.414 2.414 0 0 0 4.09 1.323l1.5-1.5.01-.01 2.477-2.477c.169-.169.443-.169.612 0a.42.42 0 0 1 .01.591c-1.228 1.272-3.37 3.46-4.993 4.953a92.183 92.183 0 0 1-2.757 2.412c-1.62 1.371-4.05 1.162-5.461-.467L5.38 15.143a4 4 0 0 1-.972-2.41l-.35-6.668a2 2 0 0 1 1.32 1.123l1.208 2.718a1 1 0 0 0 1.42.456A2.421 2.421 0 0 0 10.26 11.4c.118.294.296.57.534.807.373.373.839.599 1.323.677Zm.676-2.091 1-1a.414.414 0 1 0-.586-.586l-1 1a.414.414 0 1 0 .586.586Zm-2-2 .5-.5a.414.414 0 1 0-.586-.586l-1 1a.414.414 0 0 0 .586.586l.5-.5Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.275 4.312A1 1 0 0 1 3 4h.55a4 4 0 0 1 3.656 2.375l.616 1.388.47-.47 1.001-1a2.414 2.414 0 0 1 3.948.807 2.41 2.41 0 0 1 2.5 1.5 2.41 2.41 0 0 1 2.234 1.01l.805-.804c.95-.95 2.49-.95 3.44 0 .93.93.958 2.439.035 3.395-1.228 1.271-3.406 3.497-5.078 5.035a94 94 0 0 1-2.82 2.467c-2.481 2.1-6.156 1.748-8.264-.684L3.87 16.452a6 6 0 0 1-1.458-3.614l-.41-7.785a1 1 0 0 1 .274-.741Zm14.022 6.977-1.004 1.004-.007.006-.493.494a.414.414 0 1 1-.586-.586l1.5-1.5a.414.414 0 0 1 .59.582Zm-4.18 1.595a2.414 2.414 0 0 0 4.09 1.323l1.5-1.5.01-.01 2.477-2.477a.433.433 0 0 1 .612 0 .42.42 0 0 1 .01.591c-1.228 1.272-3.37 3.46-4.993 4.953a92 92 0 0 1-2.757 2.412c-1.62 1.371-4.05 1.162-5.461-.467L5.38 15.143a4 4 0 0 1-.972-2.41l-.35-6.668a2 2 0 0 1 1.32 1.123l1.208 2.718a1 1 0 0 0 1.42.456A2.42 2.42 0 0 0 10.26 11.4a2.41 2.41 0 0 0 1.857 1.484Zm.676-2.091 1-1a.414.414 0 1 0-.586-.586l-1 1a.414.414 0 1 0 .586.586Zm-2-2 .5-.5a.414.414 0 1 0-.586-.586l-1 1a.414.414 0 0 0 .586.586l.5-.5Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12.472 3.118A1 1 0 0 1 13 4v16a1 1 0 0 1-1.555.832L5.697 17H2a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h3.697l5.748-3.832a1 1 0 0 1 1.027-.05ZM11 5.868 6.555 8.833A1 1 0 0 1 6 9H3v6h3a1 1 0 0 1 .555.168L11 18.131V5.87Zm7.364-1.645a1 1 0 0 1 1.414 0A10.969 10.969 0 0 1 23 12c0 3.037-1.232 5.788-3.222 7.778a1 1 0 1 1-1.414-1.414A8.969 8.969 0 0 0 21 12a8.969 8.969 0 0 0-2.636-6.364 1 1 0 0 1 0-1.414Zm-3.182 3.181a1 1 0 0 1 1.414 0A6.483 6.483 0 0 1 18.5 12a6.483 6.483 0 0 1-1.904 4.597 1 1 0 0 1-1.414-1.415A4.483 4.483 0 0 0 16.5 12a4.483 4.483 0 0 0-1.318-3.182 1 1 0 0 1 0-1.414Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12.472 3.118A1 1 0 0 1 13 4v16a1 1 0 0 1-1.555.832L5.697 17H2a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h3.697l5.748-3.832a1 1 0 0 1 1.027-.05ZM11 5.868 6.555 8.833A1 1 0 0 1 6 9H3v6h3a1 1 0 0 1 .555.168L11 18.131V5.87Zm7.364-1.645a1 1 0 0 1 1.414 0A10.97 10.97 0 0 1 23 12c0 3.037-1.232 5.788-3.222 7.778a1 1 0 1 1-1.414-1.414A8.97 8.97 0 0 0 21 12a8.97 8.97 0 0 0-2.636-6.364 1 1 0 0 1 0-1.414Zm-3.182 3.181a1 1 0 0 1 1.414 0A6.48 6.48 0 0 1 18.5 12a6.48 6.48 0 0 1-1.904 4.597 1 1 0 0 1-1.414-1.415A4.48 4.48 0 0 0 16.5 12a4.48 4.48 0 0 0-1.318-3.182 1 1 0 0 1 0-1.414Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 703 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M11.26 5.227 5.02 6.899c-.734.197-1.17.95-.973 1.685l1.672 6.24c.197.734.951 1.17 1.685.973l6.24-1.672c.734-.197 1.17-.951.973-1.685L12.945 6.2a1.375 1.375 0 0 0-1.685-.973Zm-6.566.459a2.632 2.632 0 0 0-1.86 3.223l1.672 6.24a2.632 2.632 0 0 0 3.223 1.861l6.24-1.672a2.631 2.631 0 0 0 1.861-3.223l-1.672-6.24a2.632 2.632 0 0 0-3.223-1.861l-6.24 1.672Z" clip-rule="evenodd"/><path fill="#000" fill-rule="evenodd" d="M15.138 18.411a4.606 4.606 0 1 0 0-9.211 4.606 4.606 0 0 0 0 9.211Zm0 1.257a5.862 5.862 0 1 0 0-11.724 5.862 5.862 0 0 0 0 11.724Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M11.26 5.227 5.02 6.899c-.734.197-1.17.95-.973 1.685l1.672 6.24c.197.734.951 1.17 1.685.973l6.24-1.672a1.376 1.376 0 0 0 .973-1.685L12.945 6.2a1.375 1.375 0 0 0-1.685-.973Zm-6.566.459a2.63 2.63 0 0 0-1.86 3.223l1.672 6.24a2.63 2.63 0 0 0 3.223 1.861l6.24-1.672a2.63 2.63 0 0 0 1.861-3.223l-1.672-6.24a2.63 2.63 0 0 0-3.223-1.861l-6.24 1.672Z" clip-rule="evenodd"/><path fill="#000" fill-rule="evenodd" d="M15.138 18.411a4.606 4.606 0 1 0 0-9.211 4.606 4.606 0 0 0 0 9.211Zm0 1.257a5.862 5.862 0 1 0 0-11.724 5.862 5.862 0 0 0 0 11.724Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 687 B After Width: | Height: | Size: 678 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 153 133"><path fill="url(#a)" fill-rule="evenodd" d="m60.196 105.445-18.1 4.85c-11.73 3.143-23.788-3.819-26.931-15.55L1.19 42.597c-3.143-11.731 3.819-23.79 15.55-26.932L68.889 1.69C80.62-1.452 92.68 5.51 95.821 17.241l4.667 17.416a49.7 49.7 0 0 1 3.522-.125c27.053 0 48.984 21.931 48.984 48.984S131.063 132.5 104.01 132.5c-19.17 0-35.769-11.012-43.814-27.055ZM19.457 25.804 71.606 11.83c6.131-1.643 12.434 1.996 14.076 8.127l4.44 16.571c-20.289 5.987-35.096 24.758-35.096 46.988 0 4.157.517 8.193 1.492 12.047l-17.138 4.593c-6.131 1.642-12.434-1.996-14.077-8.128L11.33 39.88c-1.643-6.131 1.996-12.434 8.127-14.077Zm83.812 19.232c.246-.005.493-.007.741-.007 21.256 0 38.487 17.231 38.487 38.487s-17.231 38.488-38.487 38.488c-14.29 0-26.76-7.788-33.4-19.35l23.635-6.333c11.731-3.143 18.693-15.2 15.55-26.932l-6.526-24.353Zm-10.428 1.638 6.815 25.432c1.642 6.131-1.996 12.434-8.128 14.076l-24.867 6.664a38.57 38.57 0 0 1-1.139-9.33c0-17.372 11.51-32.056 27.32-36.842Z" clip-rule="evenodd"/><defs><linearGradient id="a" x1="76.715" x2="76.715" y1=".937" y2="132.5" gradientUnits="userSpaceOnUse"><stop stop-color="#0A7AFF"/><stop offset="1" stop-color="#59B9FF"/></linearGradient></defs></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 153 133"><path fill="url(#a)" fill-rule="evenodd" d="m60.196 105.445-18.1 4.85c-11.73 3.143-23.788-3.819-26.931-15.55L1.19 42.597c-3.143-11.731 3.819-23.79 15.55-26.932L68.889 1.69C80.62-1.452 92.68 5.51 95.821 17.241l4.667 17.416a50 50 0 0 1 3.522-.125c27.053 0 48.984 21.931 48.984 48.984S131.063 132.5 104.01 132.5c-19.17 0-35.769-11.012-43.814-27.055ZM19.457 25.804 71.606 11.83c6.131-1.643 12.434 1.996 14.076 8.127l4.44 16.571c-20.289 5.987-35.096 24.758-35.096 46.988 0 4.157.517 8.193 1.492 12.047l-17.138 4.593c-6.131 1.642-12.434-1.996-14.077-8.128L11.33 39.88c-1.643-6.131 1.996-12.434 8.127-14.077Zm83.812 19.232q.369-.007.741-.007c21.256 0 38.487 17.231 38.487 38.487s-17.231 38.488-38.487 38.488c-14.29 0-26.76-7.788-33.4-19.35l23.635-6.333c11.731-3.143 18.693-15.2 15.55-26.932l-6.526-24.353Zm-10.428 1.638 6.815 25.432c1.642 6.131-1.996 12.434-8.128 14.076l-24.867 6.664a38.6 38.6 0 0 1-1.139-9.33c0-17.372 11.51-32.056 27.32-36.842Z" clip-rule="evenodd"/><defs><linearGradient id="a" x1="76.715" x2="76.715" y1=".937" y2="132.5" gradientUnits="userSpaceOnUse"><stop stop-color="#0A7AFF"/><stop offset="1" stop-color="#59B9FF"/></linearGradient></defs></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M9 5a1 1 0 0 1 1-1h12a1 1 0 1 1 0 2h-5v14a1 1 0 1 1-2 0V6h-5a1 1 0 0 1-1-1Zm-3.073 7v8a1 1 0 1 0 2 0v-8H12a1 1 0 1 0 0-2H6.971a1.015 1.015 0 0 0-.089 0H2a1 1 0 1 0 0 2h3.927Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M9 5a1 1 0 0 1 1-1h12a1 1 0 1 1 0 2h-5v14a1 1 0 1 1-2 0V6h-5a1 1 0 0 1-1-1Zm-3.073 7v8a1 1 0 1 0 2 0v-8H12a1 1 0 1 0 0-2H2a1 1 0 1 0 0 2h3.927Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 317 B After Width: | Height: | Size: 286 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" stroke="#000" stroke-linejoin="round" d="M4 5.5a.5.5 0 0 0-.5.5v2.535a.5.5 0 0 0 .25.433A3.498 3.498 0 0 1 5.5 12a3.498 3.498 0 0 1-1.75 3.032.5.5 0 0 0-.25.433V18a.5.5 0 0 0 .5.5h16a.5.5 0 0 0 .5-.5v-2.535a.5.5 0 0 0-.25-.433A3.498 3.498 0 0 1 18.5 12a3.5 3.5 0 0 1 1.75-3.032.5.5 0 0 0 .25-.433V6a.5.5 0 0 0-.5-.5H4ZM2.5 6A1.5 1.5 0 0 1 4 4.5h16A1.5 1.5 0 0 1 21.5 6v3.17a.5.5 0 0 1-.333.472 2.501 2.501 0 0 0 0 4.716.5.5 0 0 1 .333.471V18a1.5 1.5 0 0 1-1.5 1.5H4A1.5 1.5 0 0 1 2.5 18v-3.17a.5.5 0 0 1 .333-.472 2.501 2.501 0 0 0 0-4.716.5.5 0 0 1-.333-.471V6Zm12 2a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" stroke="#000" stroke-linejoin="round" d="M4 5.5a.5.5 0 0 0-.5.5v2.535a.5.5 0 0 0 .25.433A3.5 3.5 0 0 1 5.5 12a3.5 3.5 0 0 1-1.75 3.032.5.5 0 0 0-.25.433V18a.5.5 0 0 0 .5.5h16a.5.5 0 0 0 .5-.5v-2.535a.5.5 0 0 0-.25-.433A3.5 3.5 0 0 1 18.5 12a3.5 3.5 0 0 1 1.75-3.032.5.5 0 0 0 .25-.433V6a.5.5 0 0 0-.5-.5H4ZM2.5 6A1.5 1.5 0 0 1 4 4.5h16A1.5 1.5 0 0 1 21.5 6v3.17a.5.5 0 0 1-.333.472 2.501 2.501 0 0 0 0 4.716.5.5 0 0 1 .333.471V18a1.5 1.5 0 0 1-1.5 1.5H4A1.5 1.5 0 0 1 2.5 18v-3.17a.5.5 0 0 1 .333-.472 2.501 2.501 0 0 0 0-4.716.5.5 0 0 1-.333-.471V6Zm12 2a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 768 B After Width: | Height: | Size: 756 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7.416 5H3a1 1 0 0 0 0 2h1.064l.938 14.067A1 1 0 0 0 6 22h12a1 1 0 0 0 .998-.933L19.936 7H21a1 1 0 1 0 0-2h-4.416a5 5 0 0 0-9.168 0Zm2.348 0h4.472c-.55-.614-1.348-1-2.236-1-.888 0-1.687.386-2.236 1Zm6.087 2H6.07l.867 13h10.128l.867-13h-2.036a1 1 0 0 1-.044 0ZM10 10a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0v-5a1 1 0 0 1 1-1Zm4 0a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0v-5a1 1 0 0 1 1-1Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7.416 5H3a1 1 0 0 0 0 2h1.064l.938 14.067A1 1 0 0 0 6 22h12a1 1 0 0 0 .998-.933L19.936 7H21a1 1 0 1 0 0-2h-4.416a5 5 0 0 0-9.168 0Zm2.348 0h4.472c-.55-.614-1.348-1-2.236-1s-1.687.386-2.236 1Zm6.087 2H6.07l.867 13h10.128l.867-13h-2.08ZM10 10a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0v-5a1 1 0 0 1 1-1Zm4 0a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0v-5a1 1 0 0 1 1-1Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 484 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="m18.192 5.004 1.864 5.31a1 1 0 0 0 1.887-.662L20.08 4.34c-.665-1.893-3.378-1.741-3.834.207l-3.381 14.449-2.985-9.605C9.3 7.531 6.684 7.506 6.07 9.355l-1.18 3.56-.969-2.312a1 1 0 0 0-1.844.772l.97 2.315c.715 1.71 3.159 1.613 3.741-.144l1.18-3.56 2.985 9.605c.607 1.952 3.392 1.848 3.857-.138l3.381-14.449Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="m18.192 5.004 1.864 5.31a1 1 0 0 0 1.887-.662L20.08 4.34c-.665-1.893-3.378-1.741-3.834.207l-3.381 14.449L9.88 9.391c-.58-1.86-3.196-1.885-3.81-.036l-1.18 3.56-.969-2.312a1 1 0 0 0-1.844.772l.97 2.315c.715 1.71 3.159 1.613 3.741-.144l1.18-3.56 2.985 9.605c.607 1.952 3.392 1.848 3.857-.138l3.381-14.449Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 447 B After Width: | Height: | Size: 445 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12.86 4.494a.995.995 0 0 0-1.72 0L4.14 16.502A.996.996 0 0 0 4.999 18h14.003a.996.996 0 0 0 .86-1.498L12.86 4.494ZM9.413 3.487c1.155-1.983 4.019-1.983 5.174 0l7.002 12.007C22.753 17.491 21.314 20 19.002 20H4.998c-2.312 0-3.751-2.509-2.587-4.506L9.413 3.487ZM12 8.019a1 1 0 0 1 1 1v2.994a1 1 0 1 1-2 0V9.02a1 1 0 0 1 1-1Z" clip-rule="evenodd"/><rect width="2.5" height="2.5" x="10.75" y="13.75" fill="#000" rx="1.25"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12.86 4.494a.995.995 0 0 0-1.72 0l-7 12.008A.996.996 0 0 0 4.999 18h14.003a.996.996 0 0 0 .86-1.498L12.86 4.494ZM9.413 3.487c1.155-1.983 4.019-1.983 5.174 0l7.002 12.007C22.753 17.491 21.314 20 19.002 20H4.998c-2.312 0-3.751-2.509-2.587-4.506L9.413 3.487ZM12 8.019a1 1 0 0 1 1 1v2.994a1 1 0 1 1-2 0V9.02a1 1 0 0 1 1-1Z" clip-rule="evenodd"/><rect width="2.5" height="2.5" x="10.75" y="13.75" fill="#000" rx="1.25"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 537 B After Width: | Height: | Size: 536 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7.03 6.443c-.889.17-1.707.385-2.431.638-.966.338-1.82.764-2.45 1.286C1.523 8.884 1 9.6 1 10.5c0 1.321 1.098 2.24 2.203 2.821.854.45 1.928.817 3.142 1.093l-3.19 5.052a1 1 0 1 0 1.69 1.068l5.767-9.13a8.502 8.502 0 0 1 2.776 0l5.766 9.13a1 1 0 0 0 1.692-1.068l-3.191-5.052c1.214-.276 2.288-.644 3.142-1.093 1.105-.58 2.203-1.5 2.203-2.821 0-.9-.524-1.616-1.148-2.133-.631-.522-1.485-.948-2.45-1.286a17.147 17.147 0 0 0-2.433-.638 5 5 0 0 0-9.938 0Zm2.095-.301A28.736 28.736 0 0 1 12 6c.992 0 1.957.049 2.875.142a3.001 3.001 0 0 0-5.75 0Zm7.389 6.466c1.403-.262 2.55-.635 3.352-1.057C20.87 11.023 21 10.611 21 10.5c0-.066-.036-.271-.423-.592-.381-.315-.993-.644-1.836-.939C17.063 8.382 14.68 8 12 8c-2.68 0-5.063.382-6.74.969-.844.295-1.456.624-1.837.94-.387.32-.423.525-.423.591 0 .11.13.523 1.134 1.051.802.422 1.95.795 3.352 1.057l1.441-2.282a1.952 1.952 0 0 1 1.328-.89 10.51 10.51 0 0 1 3.49 0c.57.094 1.042.437 1.328.89l1.44 2.282Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7.03 6.443a17 17 0 0 0-2.431.638c-.966.338-1.82.764-2.45 1.286C1.523 8.884 1 9.6 1 10.5c0 1.321 1.098 2.24 2.203 2.821.854.45 1.928.817 3.142 1.093l-3.19 5.052a1 1 0 1 0 1.69 1.068l5.767-9.13a8.5 8.5 0 0 1 2.776 0l5.766 9.13a1 1 0 0 0 1.692-1.068l-3.191-5.052c1.214-.276 2.288-.644 3.142-1.093 1.105-.58 2.203-1.5 2.203-2.821 0-.9-.524-1.616-1.148-2.133-.631-.522-1.485-.948-2.45-1.286a17 17 0 0 0-2.433-.638 5 5 0 0 0-9.938 0Zm2.095-.301A29 29 0 0 1 12 6c.992 0 1.957.049 2.875.142a3.001 3.001 0 0 0-5.75 0Zm7.389 6.466c1.403-.262 2.55-.635 3.352-1.057C20.87 11.023 21 10.611 21 10.5c0-.066-.036-.271-.423-.592-.381-.315-.993-.644-1.836-.939C17.063 8.382 14.68 8 12 8s-5.063.382-6.74.969c-.844.295-1.456.624-1.837.94-.387.32-.423.525-.423.591 0 .11.13.523 1.134 1.051.802.422 1.95.795 3.352 1.057l1.441-2.282a1.95 1.95 0 0 1 1.328-.89 10.5 10.5 0 0 1 3.49 0c.57.094 1.042.437 1.328.89l1.44 2.282Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10Zm3-12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm-3 10a7.976 7.976 0 0 1-5.714-2.4C7.618 16.004 9.605 15 12 15c2.396 0 4.383 1.005 5.714 2.6A7.976 7.976 0 0 1 12 20Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10Zm3-12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm-3 10a7.98 7.98 0 0 1-5.714-2.4C7.618 16.004 9.605 15 12 15s4.383 1.005 5.714 2.6A7.98 7.98 0 0 1 12 20Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 354 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a8 8 0 0 0-5.935 13.365C7.56 15.895 9.612 15 12 15c2.388 0 4.44.894 5.935 2.365A8 8 0 0 0 12 4Zm4.412 14.675C15.298 17.636 13.792 17 12 17c-1.791 0-3.298.636-4.412 1.675A7.96 7.96 0 0 0 12 20a7.96 7.96 0 0 0 4.412-1.325ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10a9.98 9.98 0 0 1-3.462 7.567A9.965 9.965 0 0 1 12 22a9.965 9.965 0 0 1-6.538-2.433A9.98 9.98 0 0 1 2 12Zm10-4a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-4 2a4 4 0 1 1 8 0 4 4 0 0 1-8 0Z" clip-rule="evenodd"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a8 8 0 0 0-5.935 13.365C7.56 15.895 9.612 15 12 15s4.44.894 5.935 2.365A8 8 0 0 0 12 4Zm4.412 14.675C15.298 17.636 13.792 17 12 17s-3.298.636-4.412 1.675A7.96 7.96 0 0 0 12 20a7.96 7.96 0 0 0 4.412-1.325ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10a9.98 9.98 0 0 1-3.462 7.567A9.97 9.97 0 0 1 12 22a9.97 9.97 0 0 1-6.538-2.433A9.98 9.98 0 0 1 2 12Zm10-4a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-4 2a4 4 0 1 1 8 0 4 4 0 0 1-8 0Z" clip-rule="evenodd"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 581 B After Width: | Height: | Size: 561 B |
@@ -32,6 +32,53 @@
|
|||||||
<link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf">
|
<link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf">
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/**
|
||||||
|
* Minimum styles required to render splash.
|
||||||
|
*
|
||||||
|
* ALL OTHER STYLES BELONG IN `src/style.css`
|
||||||
|
*
|
||||||
|
* THIS NEEDS TO BE DUPLICATED IN `bskyweb/templates/base.html`
|
||||||
|
*/
|
||||||
|
html {
|
||||||
|
background-color: white;
|
||||||
|
scrollbar-gutter: stable both-edges;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
font-family: 'Inter-Regular', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Liberation Sans', Helvetica, Arial, sans-serif;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
/* Platform-specific reset */
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-ms-overflow-style: scrollbar;
|
||||||
|
font-synthesis-weight: none;
|
||||||
|
}
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#root {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 0 auto;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
#splash {
|
||||||
|
position: fixed;
|
||||||
|
width: 100px;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateX(-50%) translateY(-50%) translateY(-50px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
{% include "scripts.html" %}
|
{% include "scripts.html" %}
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||||
@@ -48,7 +95,7 @@
|
|||||||
<body>
|
<body>
|
||||||
{%- block body_all %}
|
{%- block body_all %}
|
||||||
<div id="root">
|
<div id="root">
|
||||||
<div id="preload">
|
<div id="splash">
|
||||||
<!-- Bluesky SVG -->
|
<!-- Bluesky SVG -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 320"><path fill="#0085ff" d="M180 142c-16.3-31.7-60.7-90.8-102-120C38.5-5.9 23.4-1 13.5 3.4 2.1 8.6 0 26.2 0 36.5c0 10.4 5.7 84.8 9.4 97.2 12.2 41 55.7 55 95.7 50.5-58.7 8.6-110.8 30-42.4 106.1 75.1 77.9 103-16.7 117.3-64.6 14.3 48 30.8 139 116 64.6 64-64.6 17.6-97.5-41.1-106.1 40 4.4 83.5-9.5 95.7-50.5 3.7-12.4 9.4-86.8 9.4-97.2 0-10.3-2-27.9-13.5-33C336.5-1 321.5-6 282 22c-41.3 29.2-85.7 88.3-102 120Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 320"><path fill="#0085ff" d="M180 142c-16.3-31.7-60.7-90.8-102-120C38.5-5.9 23.4-1 13.5 3.4 2.1 8.6 0 26.2 0 36.5c0 10.4 5.7 84.8 9.4 97.2 12.2 41 55.7 55 95.7 50.5-58.7 8.6-110.8 30-42.4 106.1 75.1 77.9 103-16.7 117.3-64.6 14.3 48 30.8 139 116 64.6 64-64.6 17.6-97.5-41.1-106.1 40 4.4 83.5-9.5 95.7-50.5 3.7-12.4 9.4-86.8 9.4-97.2 0-10.3-2-27.9-13.5-33C336.5-1 321.5-6 282 22c-41.3 29.2-85.7 88.3-102 120Z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -42,8 +42,16 @@ jest.mock('rn-fetch-blob', () => ({
|
|||||||
fetch: jest.fn(),
|
fetch: jest.fn(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
jest.mock('@bam.tech/react-native-image-resizer', () => ({
|
jest.mock('expo-file-system', () => ({
|
||||||
createResizedImage: jest.fn(),
|
getInfoAsync: jest.fn().mockResolvedValue({exists: true, size: 100}),
|
||||||
|
deleteAsync: jest.fn(),
|
||||||
|
}))
|
||||||
|
|
||||||
|
jest.mock('expo-image-manipulator', () => ({
|
||||||
|
manipulateAsync: jest.fn().mockResolvedValue({
|
||||||
|
uri: 'file://resized-image',
|
||||||
|
}),
|
||||||
|
SaveFormat: jest.requireActual('expo-image-manipulator').SaveFormat,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
jest.mock('@segment/analytics-react-native', () => ({
|
jest.mock('@segment/analytics-react-native', () => ({
|
||||||
|
|||||||
@@ -2,46 +2,80 @@ import UserNotifications
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
let APP_GROUP = "group.app.bsky"
|
let APP_GROUP = "group.app.bsky"
|
||||||
|
typealias ContentHandler = (UNNotificationContent) -> Void
|
||||||
|
|
||||||
|
// This extension allows us to do some processing of the received notification
|
||||||
|
// data before displaying the notification to the user. In our use case, there
|
||||||
|
// are a few particular things that we want to do:
|
||||||
|
//
|
||||||
|
// - Determine whether we should play a sound for the notification
|
||||||
|
// - Download and display any images for the notification
|
||||||
|
// - Update the badge count accordingly
|
||||||
|
//
|
||||||
|
// The extension may or may not create a new process to handle a notification.
|
||||||
|
// It is also possible that multiple notifications will be processed by the
|
||||||
|
// same instance of `NotificationService`, though these will happen in
|
||||||
|
// parallel.
|
||||||
|
//
|
||||||
|
// Because multiple instances of `NotificationService` may exist, we should
|
||||||
|
// be careful in accessing preferences that will be mutated _by the
|
||||||
|
// extension itself_. For example, we should not worry about `playChatSound`
|
||||||
|
// changing, since we never mutate that value within the extension itself.
|
||||||
|
// However, since we mutate `badgeCount` frequently, we should ensure that
|
||||||
|
// these updates always run sync with each other and that the have access
|
||||||
|
// to the most recent values.
|
||||||
|
|
||||||
class NotificationService: UNNotificationServiceExtension {
|
class NotificationService: UNNotificationServiceExtension {
|
||||||
var prefs = UserDefaults(suiteName: APP_GROUP)
|
private var contentHandler: ContentHandler?
|
||||||
|
private var bestAttempt: UNMutableNotificationContent?
|
||||||
|
|
||||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||||
guard let bestAttempt = createCopy(request.content),
|
self.contentHandler = contentHandler
|
||||||
|
|
||||||
|
guard let bestAttempt = NSEUtil.createCopy(request.content),
|
||||||
let reason = request.content.userInfo["reason"] as? String
|
let reason = request.content.userInfo["reason"] as? String
|
||||||
else {
|
else {
|
||||||
contentHandler(request.content)
|
contentHandler(request.content)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.bestAttempt = bestAttempt
|
||||||
if reason == "chat-message" {
|
if reason == "chat-message" {
|
||||||
mutateWithChatMessage(bestAttempt)
|
mutateWithChatMessage(bestAttempt)
|
||||||
} else {
|
} else {
|
||||||
mutateWithBadge(bestAttempt)
|
mutateWithBadge(bestAttempt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Any image downloading (or other network tasks) should be handled at the end
|
||||||
|
// of this block. Otherwise, if there is a timeout and serviceExtensionTimeWillExpire
|
||||||
|
// gets called, we might not have all the needed mutations completed in time.
|
||||||
|
|
||||||
contentHandler(bestAttempt)
|
contentHandler(bestAttempt)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func serviceExtensionTimeWillExpire() {
|
override func serviceExtensionTimeWillExpire() {
|
||||||
// If for some reason the alloted time expires, we don't actually want to display a notification
|
guard let contentHandler = self.contentHandler,
|
||||||
|
let bestAttempt = self.bestAttempt else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
contentHandler(bestAttempt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createCopy(_ content: UNNotificationContent) -> UNMutableNotificationContent? {
|
// MARK: Mutations
|
||||||
return content.mutableCopy() as? UNMutableNotificationContent
|
|
||||||
}
|
|
||||||
|
|
||||||
func mutateWithBadge(_ content: UNMutableNotificationContent) {
|
func mutateWithBadge(_ content: UNMutableNotificationContent) {
|
||||||
var count = prefs?.integer(forKey: "badgeCount") ?? 0
|
NSEUtil.shared.prefsQueue.sync {
|
||||||
|
var count = NSEUtil.shared.prefs?.integer(forKey: "badgeCount") ?? 0
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
// Set the new badge number for the notification, then store that value for using later
|
// Set the new badge number for the notification, then store that value for using later
|
||||||
content.badge = NSNumber(value: count)
|
content.badge = NSNumber(value: count)
|
||||||
prefs?.setValue(count, forKey: "badgeCount")
|
NSEUtil.shared.prefs?.setValue(count, forKey: "badgeCount")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mutateWithChatMessage(_ content: UNMutableNotificationContent) {
|
func mutateWithChatMessage(_ content: UNMutableNotificationContent) {
|
||||||
if self.prefs?.bool(forKey: "playSoundChat") == true {
|
if NSEUtil.shared.prefs?.bool(forKey: "playSoundChat") == true {
|
||||||
mutateWithDmSound(content)
|
mutateWithDmSound(content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,3 +88,18 @@ class NotificationService: UNNotificationServiceExtension {
|
|||||||
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "dm.aiff"))
|
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "dm.aiff"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NSEUtil's purpose is to create a shared instance of `UserDefaults` across
|
||||||
|
// `NotificationService` instances. It also includes a queue so that we can process
|
||||||
|
// updates to `UserDefaults` in parallel.
|
||||||
|
|
||||||
|
private class NSEUtil {
|
||||||
|
static let shared = NSEUtil()
|
||||||
|
|
||||||
|
var prefs = UserDefaults(suiteName: APP_GROUP)
|
||||||
|
var prefsQueue = DispatchQueue(label: "NSEPrefsQueue")
|
||||||
|
|
||||||
|
static func createCopy(_ content: UNNotificationContent) -> UNMutableNotificationContent? {
|
||||||
|
return content.mutableCopy() as? UNMutableNotificationContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||||
<integer>10</integer>
|
<integer>10</integer>
|
||||||
|
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||||
|
<integer>1</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>NSExtensionPointIdentifier</key>
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ class ShareViewController: UIViewController {
|
|||||||
// scheme.
|
// scheme.
|
||||||
let appScheme = Bundle.main.object(forInfoDictionaryKey: "MainAppScheme") as? String ?? "bluesky"
|
let appScheme = Bundle.main.object(forInfoDictionaryKey: "MainAppScheme") as? String ?? "bluesky"
|
||||||
|
|
||||||
//
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
@@ -24,6 +23,8 @@ class ShareViewController: UIViewController {
|
|||||||
await self.handleUrl(item: firstAttachment)
|
await self.handleUrl(item: firstAttachment)
|
||||||
} else if firstAttachment.hasItemConformingToTypeIdentifier("public.image") {
|
} else if firstAttachment.hasItemConformingToTypeIdentifier("public.image") {
|
||||||
await self.handleImages(items: attachments)
|
await self.handleImages(items: attachments)
|
||||||
|
} else if firstAttachment.hasItemConformingToTypeIdentifier("public.video") {
|
||||||
|
await self.handleVideos(items: attachments)
|
||||||
} else {
|
} else {
|
||||||
self.completeRequest()
|
self.completeRequest()
|
||||||
}
|
}
|
||||||
@@ -31,31 +32,23 @@ class ShareViewController: UIViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func handleText(item: NSItemProvider) async {
|
private func handleText(item: NSItemProvider) async {
|
||||||
do {
|
if let data = try? await item.loadItem(forTypeIdentifier: "public.text") as? String {
|
||||||
if let data = try await item.loadItem(forTypeIdentifier: "public.text") as? String {
|
|
||||||
if let encoded = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
if let encoded = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
||||||
_ = self.openURL(url)
|
_ = self.openURL(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.completeRequest()
|
self.completeRequest()
|
||||||
} catch {
|
|
||||||
self.completeRequest()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleUrl(item: NSItemProvider) async {
|
private func handleUrl(item: NSItemProvider) async {
|
||||||
do {
|
if let data = try? await item.loadItem(forTypeIdentifier: "public.url") as? URL {
|
||||||
if let data = try await item.loadItem(forTypeIdentifier: "public.url") as? URL {
|
|
||||||
if let encoded = data.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
if let encoded = data.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
||||||
_ = self.openURL(url)
|
_ = self.openURL(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.completeRequest()
|
self.completeRequest()
|
||||||
} catch {
|
|
||||||
self.completeRequest()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleImages(items: [NSItemProvider]) async {
|
private func handleImages(items: [NSItemProvider]) async {
|
||||||
@@ -105,6 +98,25 @@ class ShareViewController: UIViewController {
|
|||||||
self.completeRequest()
|
self.completeRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func handleVideos(items: [NSItemProvider]) async {
|
||||||
|
let firstItem = items.first
|
||||||
|
|
||||||
|
if let dataUri = try? await firstItem?.loadItem(forTypeIdentifier: "public.video") as? URL {
|
||||||
|
let ext = String(dataUri.lastPathComponent.split(separator: ".").last ?? "mp4")
|
||||||
|
if let tempUrl = getTempUrl(ext: ext) {
|
||||||
|
let data = try? Data(contentsOf: dataUri)
|
||||||
|
try? data?.write(to: tempUrl)
|
||||||
|
|
||||||
|
if let encoded = dataUri.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
|
let url = URL(string: "\(self.appScheme)://intent/compose?videoUri=\(encoded)") {
|
||||||
|
_ = self.openURL(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.completeRequest()
|
||||||
|
}
|
||||||
|
|
||||||
private func saveImageWithInfo(_ image: UIImage?) -> String? {
|
private func saveImageWithInfo(_ image: UIImage?) -> String? {
|
||||||
guard let image = image else {
|
guard let image = image else {
|
||||||
return nil
|
return nil
|
||||||
@@ -114,27 +126,26 @@ class ShareViewController: UIViewController {
|
|||||||
// Saving this file to the bundle group's directory lets us access it from
|
// Saving this file to the bundle group's directory lets us access it from
|
||||||
// inside of the app. Otherwise, we wouldn't have access even though the
|
// inside of the app. Otherwise, we wouldn't have access even though the
|
||||||
// extension does.
|
// extension does.
|
||||||
if let dir = FileManager()
|
if let tempUrl = getTempUrl(ext: "jpeg"),
|
||||||
.containerURL(
|
|
||||||
forSecurityApplicationGroupIdentifier: "group.app.bsky") {
|
|
||||||
let filePath = "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).jpeg"
|
|
||||||
|
|
||||||
if let newUri = URL(string: filePath),
|
|
||||||
let jpegData = image.jpegData(compressionQuality: 1) {
|
let jpegData = image.jpegData(compressionQuality: 1) {
|
||||||
try jpegData.write(to: newUri)
|
try jpegData.write(to: tempUrl)
|
||||||
return "\(newUri.absoluteString)|\(image.size.width)|\(image.size.height)"
|
return "\(tempUrl.absoluteString)|\(image.size.width)|\(image.size.height)"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch {}
|
||||||
return nil
|
return nil
|
||||||
} catch {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func completeRequest() {
|
private func completeRequest() {
|
||||||
self.extensionContext?.completeRequest(returningItems: nil)
|
self.extensionContext?.completeRequest(returningItems: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func getTempUrl(ext: String) -> URL? {
|
||||||
|
if let dir = FileManager().containerURL(forSecurityApplicationGroupIdentifier: "group.app.bsky") {
|
||||||
|
return URL(string: "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).\(ext)")!
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
@objc func openURL(_ url: URL) -> Bool {
|
@objc func openURL(_ url: URL) -> Bool {
|
||||||
var responder: UIResponder? = self
|
var responder: UIResponder? = self
|
||||||
while responder != nil {
|
while responder != nil {
|
||||||
|
|||||||
@@ -49,11 +49,11 @@
|
|||||||
"export": "npx expo export",
|
"export": "npx expo export",
|
||||||
"make-deploy-bundle": "bash scripts/bundleUpdate.sh",
|
"make-deploy-bundle": "bash scripts/bundleUpdate.sh",
|
||||||
"generate-webpack-stats-file": "EXPO_PUBLIC_GENERATE_STATS=1 yarn build-web",
|
"generate-webpack-stats-file": "EXPO_PUBLIC_GENERATE_STATS=1 yarn build-web",
|
||||||
"open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 yarn build-web"
|
"open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 yarn build-web",
|
||||||
|
"icons:optimize": "svgo -f ./assets/icons"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@atproto/api": "^0.13.7",
|
"@atproto/api": "^0.13.7",
|
||||||
"@bam.tech/react-native-image-resizer": "^3.0.4",
|
|
||||||
"@braintree/sanitize-url": "^6.0.2",
|
"@braintree/sanitize-url": "^6.0.2",
|
||||||
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
||||||
"@emoji-mart/react": "^1.1.1",
|
"@emoji-mart/react": "^1.1.1",
|
||||||
@@ -160,24 +160,20 @@
|
|||||||
"lodash.set": "^4.3.2",
|
"lodash.set": "^4.3.2",
|
||||||
"lodash.shuffle": "^4.2.0",
|
"lodash.shuffle": "^4.2.0",
|
||||||
"lodash.throttle": "^4.1.1",
|
"lodash.throttle": "^4.1.1",
|
||||||
"mobx": "^6.6.1",
|
|
||||||
"mobx-react-lite": "^3.4.0",
|
|
||||||
"mobx-utils": "^6.0.6",
|
|
||||||
"nanoid": "^5.0.5",
|
"nanoid": "^5.0.5",
|
||||||
"normalize-url": "^8.0.0",
|
"normalize-url": "^8.0.0",
|
||||||
"patch-package": "^6.5.1",
|
"patch-package": "^6.5.1",
|
||||||
"postinstall-postinstall": "^2.1.0",
|
"postinstall-postinstall": "^2.1.0",
|
||||||
"psl": "^1.9.0",
|
"psl": "^1.9.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-avatar-editor": "^13.0.0",
|
|
||||||
"react-compiler-runtime": "file:./lib/react-compiler-runtime",
|
"react-compiler-runtime": "file:./lib/react-compiler-runtime",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-image-crop": "^11.0.7",
|
||||||
"react-keyed-flatten-children": "^3.0.0",
|
"react-keyed-flatten-children": "^3.0.0",
|
||||||
"react-native": "0.74.1",
|
"react-native": "0.74.1",
|
||||||
"react-native-compressor": "^1.8.24",
|
"react-native-compressor": "^1.8.24",
|
||||||
"react-native-date-picker": "^4.4.2",
|
"react-native-date-picker": "^4.4.2",
|
||||||
"react-native-drawer-layout": "^4.0.0-alpha.3",
|
"react-native-drawer-layout": "^4.0.0-alpha.3",
|
||||||
"react-native-fs": "^2.20.0",
|
|
||||||
"react-native-gesture-handler": "~2.16.2",
|
"react-native-gesture-handler": "~2.16.2",
|
||||||
"react-native-get-random-values": "~1.11.0",
|
"react-native-get-random-values": "~1.11.0",
|
||||||
"react-native-image-crop-picker": "0.41.2",
|
"react-native-image-crop-picker": "0.41.2",
|
||||||
@@ -238,7 +234,6 @@
|
|||||||
"@types/lodash.set": "^4.3.7",
|
"@types/lodash.set": "^4.3.7",
|
||||||
"@types/lodash.shuffle": "^4.2.7",
|
"@types/lodash.shuffle": "^4.2.7",
|
||||||
"@types/psl": "^1.1.1",
|
"@types/psl": "^1.1.1",
|
||||||
"@types/react-avatar-editor": "^13.0.0",
|
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.18",
|
||||||
"@types/react-responsive": "^8.0.5",
|
"@types/react-responsive": "^8.0.5",
|
||||||
"@types/react-test-renderer": "^17.0.1",
|
"@types/react-test-renderer": "^17.0.1",
|
||||||
@@ -272,6 +267,7 @@
|
|||||||
"react-refresh": "^0.14.0",
|
"react-refresh": "^0.14.0",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"react-test-renderer": "18.2.0",
|
"react-test-renderer": "18.2.0",
|
||||||
|
"svgo": "^3.3.2",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^5.5.4",
|
"typescript": "^5.5.4",
|
||||||
"url-loader": "^4.1.1",
|
"url-loader": "^4.1.1",
|
||||||
@@ -343,6 +339,9 @@
|
|||||||
],
|
],
|
||||||
"*{.js,.jsx,.ts,.tsx,.css}": [
|
"*{.js,.jsx,.ts,.tsx,.css}": [
|
||||||
"prettier --cache --write --ignore-unknown"
|
"prettier --cache --write --ignore-unknown"
|
||||||
|
],
|
||||||
|
"assets/icons/*.svg": [
|
||||||
|
"svgo"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ function EmbedDialogInner({
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={[a.flex_row, a.gap_sm]}>
|
<View style={[a.flex_row, a.gap_sm]}>
|
||||||
|
<View style={[a.flex_1]}>
|
||||||
<TextField.Root>
|
<TextField.Root>
|
||||||
<TextField.Icon icon={CodeBrackets} />
|
<TextField.Icon icon={CodeBrackets} />
|
||||||
<TextField.Input
|
<TextField.Input
|
||||||
@@ -116,6 +117,7 @@ function EmbedDialogInner({
|
|||||||
style={{}}
|
style={{}}
|
||||||
/>
|
/>
|
||||||
</TextField.Root>
|
</TextField.Root>
|
||||||
|
</View>
|
||||||
<Button
|
<Button
|
||||||
label={_(msg`Copy code`)}
|
label={_(msg`Copy code`)}
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import {
|
|||||||
ViewStyle,
|
ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
|
||||||
|
import {HITSLOP_20} from '#/lib/constants'
|
||||||
import {mergeRefs} from '#/lib/merge-refs'
|
import {mergeRefs} from '#/lib/merge-refs'
|
||||||
import {HITSLOP_20} from 'lib/constants'
|
|
||||||
import {android, atoms as a, useTheme, web} from '#/alf'
|
import {android, atoms as a, useTheme, web} from '#/alf'
|
||||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
import {Props as SVGIconProps} from '#/components/icons/common'
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
@@ -73,7 +73,7 @@ export function Root({children, isInvalid = false}: RootProps) {
|
|||||||
return (
|
return (
|
||||||
<Context.Provider value={context}>
|
<Context.Provider value={context}>
|
||||||
<View
|
<View
|
||||||
style={[a.flex_row, a.align_center, a.relative, a.flex_1, a.px_md]}
|
style={[a.flex_row, a.align_center, a.relative, a.w_full, a.px_md]}
|
||||||
{...web({
|
{...web({
|
||||||
onClick: () => inputRef.current?.focus(),
|
onClick: () => inputRef.current?.focus(),
|
||||||
onMouseOver: onHoverIn,
|
onMouseOver: onHoverIn,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
|
import {ComposerImage, compressImage} from '#/state/gallery'
|
||||||
import {writePostgateRecord} from '#/state/queries/postgate'
|
import {writePostgateRecord} from '#/state/queries/postgate'
|
||||||
import {
|
import {
|
||||||
createThreadgateRecord,
|
createThreadgateRecord,
|
||||||
@@ -23,10 +24,7 @@ import {
|
|||||||
} from '#/state/queries/threadgate'
|
} from '#/state/queries/threadgate'
|
||||||
import {isNetworkError} from 'lib/strings/errors'
|
import {isNetworkError} from 'lib/strings/errors'
|
||||||
import {shortenLinks, stripInvalidMentions} from 'lib/strings/rich-text-manip'
|
import {shortenLinks, stripInvalidMentions} from 'lib/strings/rich-text-manip'
|
||||||
import {isNative} from 'platform/detection'
|
|
||||||
import {ImageModel} from 'state/models/media/image'
|
|
||||||
import {LinkMeta} from '../link-meta/link-meta'
|
import {LinkMeta} from '../link-meta/link-meta'
|
||||||
import {safeDeleteAsync} from '../media/manip'
|
|
||||||
import {uploadBlob} from './upload-blob'
|
import {uploadBlob} from './upload-blob'
|
||||||
|
|
||||||
export {uploadBlob}
|
export {uploadBlob}
|
||||||
@@ -36,7 +34,7 @@ export interface ExternalEmbedDraft {
|
|||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
meta?: LinkMeta
|
meta?: LinkMeta
|
||||||
embed?: AppBskyEmbedRecord.Main
|
embed?: AppBskyEmbedRecord.Main
|
||||||
localThumb?: ImageModel
|
localThumb?: ComposerImage
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PostOpts {
|
interface PostOpts {
|
||||||
@@ -53,7 +51,7 @@ interface PostOpts {
|
|||||||
aspectRatio?: AppBskyEmbedDefs.AspectRatio
|
aspectRatio?: AppBskyEmbedDefs.AspectRatio
|
||||||
}
|
}
|
||||||
extLink?: ExternalEmbedDraft
|
extLink?: ExternalEmbedDraft
|
||||||
images?: ImageModel[]
|
images?: ComposerImage[]
|
||||||
labels?: string[]
|
labels?: string[]
|
||||||
threadgate: ThreadgateAllowUISetting[]
|
threadgate: ThreadgateAllowUISetting[]
|
||||||
postgate: AppBskyFeedPostgate.Record
|
postgate: AppBskyFeedPostgate.Record
|
||||||
@@ -99,18 +97,16 @@ export async function post(agent: BskyAgent, opts: PostOpts) {
|
|||||||
const images: AppBskyEmbedImages.Image[] = []
|
const images: AppBskyEmbedImages.Image[] = []
|
||||||
for (const image of opts.images) {
|
for (const image of opts.images) {
|
||||||
opts.onStateChange?.(`Uploading image #${images.length + 1}...`)
|
opts.onStateChange?.(`Uploading image #${images.length + 1}...`)
|
||||||
|
|
||||||
logger.debug(`Compressing image`)
|
logger.debug(`Compressing image`)
|
||||||
await image.compress()
|
const {path, width, height, mime} = await compressImage(image)
|
||||||
const path = image.compressed?.path ?? image.path
|
|
||||||
const {width, height} = image.compressed || image
|
|
||||||
logger.debug(`Uploading image`)
|
logger.debug(`Uploading image`)
|
||||||
const res = await uploadBlob(agent, path, 'image/jpeg')
|
const res = await uploadBlob(agent, path, mime)
|
||||||
if (isNative) {
|
|
||||||
safeDeleteAsync(path)
|
|
||||||
}
|
|
||||||
images.push({
|
images.push({
|
||||||
image: res.data.blob,
|
image: res.data.blob,
|
||||||
alt: image.altText ?? '',
|
alt: image.alt,
|
||||||
aspectRatio: {width, height},
|
aspectRatio: {width, height},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -175,32 +171,11 @@ export async function post(agent: BskyAgent, opts: PostOpts) {
|
|||||||
let thumb
|
let thumb
|
||||||
if (opts.extLink.localThumb) {
|
if (opts.extLink.localThumb) {
|
||||||
opts.onStateChange?.('Uploading link thumbnail...')
|
opts.onStateChange?.('Uploading link thumbnail...')
|
||||||
let encoding
|
|
||||||
if (opts.extLink.localThumb.mime) {
|
const {path, mime} = opts.extLink.localThumb.source
|
||||||
encoding = opts.extLink.localThumb.mime
|
const res = await uploadBlob(agent, path, mime)
|
||||||
} else if (opts.extLink.localThumb.path.endsWith('.png')) {
|
|
||||||
encoding = 'image/png'
|
thumb = res.data.blob
|
||||||
} else if (
|
|
||||||
opts.extLink.localThumb.path.endsWith('.jpeg') ||
|
|
||||||
opts.extLink.localThumb.path.endsWith('.jpg')
|
|
||||||
) {
|
|
||||||
encoding = 'image/jpeg'
|
|
||||||
} else {
|
|
||||||
logger.warn('Unexpected image format for thumbnail, skipping', {
|
|
||||||
thumbnail: opts.extLink.localThumb.path,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (encoding) {
|
|
||||||
const thumbUploadRes = await uploadBlob(
|
|
||||||
agent,
|
|
||||||
opts.extLink.localThumb.path,
|
|
||||||
encoding,
|
|
||||||
)
|
|
||||||
thumb = thumbUploadRes.data.blob
|
|
||||||
if (isNative) {
|
|
||||||
safeDeleteAsync(opts.extLink.localThumb.path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.quote) {
|
if (opts.quote) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import RNFS from 'react-native-fs'
|
import {copyAsync} from 'expo-file-system'
|
||||||
import {BskyAgent, ComAtprotoRepoUploadBlob} from '@atproto/api'
|
import {BskyAgent, ComAtprotoRepoUploadBlob} from '@atproto/api'
|
||||||
|
|
||||||
|
import {safeDeleteAsync} from '#/lib/media/manip'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param encoding Allows overriding the blob's type
|
* @param encoding Allows overriding the blob's type
|
||||||
*/
|
*/
|
||||||
@@ -65,7 +67,7 @@ async function withSafeFile<T>(
|
|||||||
// temporary file).
|
// temporary file).
|
||||||
const newPath = uri.replace(/\.jpe?g$/, '.bin')
|
const newPath = uri.replace(/\.jpe?g$/, '.bin')
|
||||||
try {
|
try {
|
||||||
await RNFS.copyFile(uri, newPath)
|
await copyAsync({from: uri, to: newPath})
|
||||||
} catch {
|
} catch {
|
||||||
// Failed to copy the file, just use the original
|
// Failed to copy the file, just use the original
|
||||||
return await fn(uri)
|
return await fn(uri)
|
||||||
@@ -74,7 +76,7 @@ async function withSafeFile<T>(
|
|||||||
return await fn(newPath)
|
return await fn(newPath)
|
||||||
} finally {
|
} finally {
|
||||||
// Remove the temporary file
|
// Remove the temporary file
|
||||||
await RNFS.unlink(newPath)
|
await safeDeleteAsync(newPath)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fn(uri)
|
return fn(uri)
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {impactAsync, ImpactFeedbackStyle} from 'expo-haptics'
|
import {impactAsync, ImpactFeedbackStyle} from 'expo-haptics'
|
||||||
|
|
||||||
import {isIOS, isWeb} from 'platform/detection'
|
import {isIOS, isWeb} from '#/platform/detection'
|
||||||
import {useHapticsDisabled} from 'state/preferences/disable-haptics'
|
import {useHapticsDisabled} from '#/state/preferences/disable-haptics'
|
||||||
|
|
||||||
const hapticImpact: ImpactFeedbackStyle = isIOS
|
|
||||||
? ImpactFeedbackStyle.Medium
|
|
||||||
: ImpactFeedbackStyle.Light // Users said the medium impact was too strong on Android; see APP-537s
|
|
||||||
|
|
||||||
export function useHaptics() {
|
export function useHaptics() {
|
||||||
const isHapticsDisabled = useHapticsDisabled()
|
const isHapticsDisabled = useHapticsDisabled()
|
||||||
|
|
||||||
return React.useCallback(() => {
|
return React.useCallback(
|
||||||
|
(strength: 'Light' | 'Medium' | 'Heavy' = 'Medium') => {
|
||||||
if (isHapticsDisabled || isWeb) {
|
if (isHapticsDisabled || isWeb) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
impactAsync(hapticImpact)
|
|
||||||
}, [isHapticsDisabled])
|
// Users said the medium impact was too strong on Android; see APP-537s
|
||||||
|
const style = isIOS
|
||||||
|
? ImpactFeedbackStyle[strength]
|
||||||
|
: ImpactFeedbackStyle.Light
|
||||||
|
impactAsync(style)
|
||||||
|
},
|
||||||
|
[isHapticsDisabled],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,20 @@ import {
|
|||||||
copyAsync,
|
copyAsync,
|
||||||
deleteAsync,
|
deleteAsync,
|
||||||
EncodingType,
|
EncodingType,
|
||||||
|
getInfoAsync,
|
||||||
makeDirectoryAsync,
|
makeDirectoryAsync,
|
||||||
StorageAccessFramework,
|
StorageAccessFramework,
|
||||||
writeAsStringAsync,
|
writeAsStringAsync,
|
||||||
} from 'expo-file-system'
|
} from 'expo-file-system'
|
||||||
|
import {manipulateAsync, SaveFormat} from 'expo-image-manipulator'
|
||||||
import * as MediaLibrary from 'expo-media-library'
|
import * as MediaLibrary from 'expo-media-library'
|
||||||
import * as Sharing from 'expo-sharing'
|
import * as Sharing from 'expo-sharing'
|
||||||
import ImageResizer from '@bam.tech/react-native-image-resizer'
|
|
||||||
import {Buffer} from 'buffer'
|
import {Buffer} from 'buffer'
|
||||||
import RNFetchBlob from 'rn-fetch-blob'
|
import RNFetchBlob from 'rn-fetch-blob'
|
||||||
|
|
||||||
|
import {POST_IMG_MAX} from '#/lib/constants'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isAndroid, isIOS} from 'platform/detection'
|
import {isAndroid, isIOS} from '#/platform/detection'
|
||||||
import {Dimensions} from './types'
|
import {Dimensions} from './types'
|
||||||
|
|
||||||
export async function compressIfNeeded(
|
export async function compressIfNeeded(
|
||||||
@@ -165,29 +167,47 @@ interface DoResizeOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function doResize(localUri: string, opts: DoResizeOpts): Promise<Image> {
|
async function doResize(localUri: string, opts: DoResizeOpts): Promise<Image> {
|
||||||
|
// We need to get the dimensions of the image before we resize it. Previously, the library we used allowed us to enter
|
||||||
|
// a "max size", and it would do the "best possible size" calculation for us.
|
||||||
|
// Now instead, we have to supply the final dimensions to the manipulation function instead.
|
||||||
|
// Performing an "empty" manipulation lets us get the dimensions of the original image. React Native's Image.getSize()
|
||||||
|
// does not work for local files...
|
||||||
|
const imageRes = await manipulateAsync(localUri, [], {})
|
||||||
|
const newDimensions = getResizedDimensions({
|
||||||
|
width: imageRes.width,
|
||||||
|
height: imageRes.height,
|
||||||
|
})
|
||||||
|
|
||||||
for (let i = 0; i < 9; i++) {
|
for (let i = 0; i < 9; i++) {
|
||||||
const quality = 100 - i * 10
|
// nearest 10th
|
||||||
const resizeRes = await ImageResizer.createResizedImage(
|
const quality = Math.round((1 - 0.1 * i) * 10) / 10
|
||||||
|
const resizeRes = await manipulateAsync(
|
||||||
localUri,
|
localUri,
|
||||||
opts.width,
|
[{resize: newDimensions}],
|
||||||
opts.height,
|
{
|
||||||
'JPEG',
|
format: SaveFormat.JPEG,
|
||||||
quality,
|
compress: quality,
|
||||||
undefined,
|
},
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
{mode: opts.mode},
|
|
||||||
)
|
)
|
||||||
if (resizeRes.size < opts.maxSize) {
|
|
||||||
|
const fileInfo = await getInfoAsync(resizeRes.uri)
|
||||||
|
if (!fileInfo.exists) {
|
||||||
|
throw new Error(
|
||||||
|
'The image manipulation library failed to create a new image.',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileInfo.size < opts.maxSize) {
|
||||||
|
safeDeleteAsync(imageRes.uri)
|
||||||
return {
|
return {
|
||||||
path: normalizePath(resizeRes.path),
|
path: normalizePath(resizeRes.uri),
|
||||||
mime: 'image/jpeg',
|
mime: 'image/jpeg',
|
||||||
size: resizeRes.size,
|
size: fileInfo.size,
|
||||||
width: resizeRes.width,
|
width: resizeRes.width,
|
||||||
height: resizeRes.height,
|
height: resizeRes.height,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
safeDeleteAsync(resizeRes.path)
|
safeDeleteAsync(resizeRes.uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -311,3 +331,25 @@ async function withTempFile<T>(
|
|||||||
safeDeleteAsync(tmpDirUri)
|
safeDeleteAsync(tmpDirUri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getResizedDimensions(originalDims: {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}) {
|
||||||
|
if (
|
||||||
|
originalDims.width <= POST_IMG_MAX.width &&
|
||||||
|
originalDims.height <= POST_IMG_MAX.height
|
||||||
|
) {
|
||||||
|
return originalDims
|
||||||
|
}
|
||||||
|
|
||||||
|
const ratio = Math.min(
|
||||||
|
POST_IMG_MAX.width / originalDims.width,
|
||||||
|
POST_IMG_MAX.height / originalDims.height,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
width: Math.round(originalDims.width * ratio),
|
||||||
|
height: Math.round(originalDims.height * ratio),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,25 +1,37 @@
|
|||||||
import RNFS from 'react-native-fs'
|
|
||||||
import {
|
import {
|
||||||
Image as RNImage,
|
Image as RNImage,
|
||||||
openCropper as openCropperFn,
|
openCropper as openCropperFn,
|
||||||
} from 'react-native-image-crop-picker'
|
} from 'react-native-image-crop-picker'
|
||||||
|
import {
|
||||||
|
documentDirectory,
|
||||||
|
getInfoAsync,
|
||||||
|
readDirectoryAsync,
|
||||||
|
} from 'expo-file-system'
|
||||||
|
|
||||||
import {compressIfNeeded} from './manip'
|
import {compressIfNeeded} from './manip'
|
||||||
import {CropperOptions} from './types'
|
import {CropperOptions} from './types'
|
||||||
|
|
||||||
async function getFile() {
|
async function getFile() {
|
||||||
let files = await RNFS.readDir(
|
const imagesDir = documentDirectory!
|
||||||
RNFS.LibraryDirectoryPath.split('/')
|
.split('/')
|
||||||
.slice(0, -5)
|
.slice(0, -6)
|
||||||
.concat(['Media', 'DCIM', '100APPLE'])
|
.concat(['Media', 'DCIM', '100APPLE'])
|
||||||
.join('/'),
|
.join('/')
|
||||||
)
|
|
||||||
files = files.filter(file => file.path.endsWith('.JPG'))
|
let files = await readDirectoryAsync(imagesDir)
|
||||||
const file = files[0]
|
files = files.filter(file => file.endsWith('.JPG'))
|
||||||
|
const file = `${imagesDir}/${files[0]}`
|
||||||
|
|
||||||
|
const fileInfo = await getInfoAsync(file)
|
||||||
|
|
||||||
|
if (!fileInfo.exists) {
|
||||||
|
throw new Error('Failed to get file info')
|
||||||
|
}
|
||||||
|
|
||||||
return await compressIfNeeded({
|
return await compressIfNeeded({
|
||||||
path: file.path,
|
path: file,
|
||||||
mime: 'image/jpeg',
|
mime: 'image/jpeg',
|
||||||
size: file.size,
|
size: fileInfo.size,
|
||||||
width: 4288,
|
width: 4288,
|
||||||
height: 2848,
|
height: 2848,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export async function openPicker(opts?: ImagePickerOptions) {
|
|||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
.map(image => ({
|
.map(image => ({
|
||||||
mime: 'image/jpeg',
|
mime: image.mimeType || 'image/jpeg',
|
||||||
height: image.height,
|
height: image.height,
|
||||||
width: image.width,
|
width: image.width,
|
||||||
path: image.uri,
|
path: image.uri,
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ export async function openCropper(opts: CropperOptions): Promise<RNImage> {
|
|||||||
name: 'crop-image',
|
name: 'crop-image',
|
||||||
uri: opts.path,
|
uri: opts.path,
|
||||||
dimensions:
|
dimensions:
|
||||||
opts.height && opts.width
|
opts.width && opts.height
|
||||||
? {width: opts.width, height: opts.height}
|
? {width: opts.width, height: opts.height}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
aspect: opts.webAspectRatio,
|
||||||
|
circular: opts.webCircularCrop,
|
||||||
onSelect: (img?: RNImage) => {
|
onSelect: (img?: RNImage) => {
|
||||||
if (img) {
|
if (img) {
|
||||||
resolve(img)
|
resolve(img)
|
||||||
|
|||||||
@@ -18,4 +18,7 @@ export interface CameraOpts {
|
|||||||
cropperCircleOverlay?: boolean
|
cropperCircleOverlay?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CropperOptions = Parameters<typeof openCropper>[0]
|
export type CropperOptions = Parameters<typeof openCropper>[0] & {
|
||||||
|
webAspectRatio?: number
|
||||||
|
webCircularCrop?: boolean
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,299 @@
|
|||||||
|
import {
|
||||||
|
cacheDirectory,
|
||||||
|
deleteAsync,
|
||||||
|
makeDirectoryAsync,
|
||||||
|
moveAsync,
|
||||||
|
} from 'expo-file-system'
|
||||||
|
import {
|
||||||
|
Action,
|
||||||
|
ActionCrop,
|
||||||
|
manipulateAsync,
|
||||||
|
SaveFormat,
|
||||||
|
} from 'expo-image-manipulator'
|
||||||
|
import {nanoid} from 'nanoid/non-secure'
|
||||||
|
|
||||||
|
import {POST_IMG_MAX} from '#/lib/constants'
|
||||||
|
import {getImageDim} from '#/lib/media/manip'
|
||||||
|
import {openCropper} from '#/lib/media/picker'
|
||||||
|
import {getDataUriSize} from '#/lib/media/util'
|
||||||
|
import {isIOS, isNative} from '#/platform/detection'
|
||||||
|
|
||||||
|
export type ImageTransformation = {
|
||||||
|
crop?: ActionCrop['crop']
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ImageMeta = {
|
||||||
|
path: string
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
mime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ImageSource = ImageMeta & {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComposerImageBase = {
|
||||||
|
alt: string
|
||||||
|
source: ImageSource
|
||||||
|
}
|
||||||
|
type ComposerImageWithoutTransformation = ComposerImageBase & {
|
||||||
|
transformed?: undefined
|
||||||
|
manips?: undefined
|
||||||
|
}
|
||||||
|
type ComposerImageWithTransformation = ComposerImageBase & {
|
||||||
|
transformed: ImageMeta
|
||||||
|
manips?: ImageTransformation
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ComposerImage =
|
||||||
|
| ComposerImageWithoutTransformation
|
||||||
|
| ComposerImageWithTransformation
|
||||||
|
|
||||||
|
let _imageCacheDirectory: string
|
||||||
|
|
||||||
|
function getImageCacheDirectory(): string | null {
|
||||||
|
if (isNative) {
|
||||||
|
return (_imageCacheDirectory ??= joinPath(cacheDirectory!, 'bsky-composer'))
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createComposerImage(
|
||||||
|
raw: ImageMeta,
|
||||||
|
): Promise<ComposerImageWithoutTransformation> {
|
||||||
|
return {
|
||||||
|
alt: '',
|
||||||
|
source: {
|
||||||
|
id: nanoid(),
|
||||||
|
path: await moveIfNecessary(raw.path),
|
||||||
|
width: raw.width,
|
||||||
|
height: raw.height,
|
||||||
|
mime: raw.mime,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type InitialImage = {
|
||||||
|
uri: string
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
altText?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createInitialImages(
|
||||||
|
uris: InitialImage[] = [],
|
||||||
|
): ComposerImageWithoutTransformation[] {
|
||||||
|
return uris.map(({uri, width, height, altText = ''}) => {
|
||||||
|
return {
|
||||||
|
alt: altText,
|
||||||
|
source: {
|
||||||
|
id: nanoid(),
|
||||||
|
path: uri,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
mime: 'image/jpeg',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function pasteImage(
|
||||||
|
uri: string,
|
||||||
|
): Promise<ComposerImageWithoutTransformation> {
|
||||||
|
const {width, height} = await getImageDim(uri)
|
||||||
|
const match = /^data:(.+?);/.exec(uri)
|
||||||
|
|
||||||
|
return {
|
||||||
|
alt: '',
|
||||||
|
source: {
|
||||||
|
id: nanoid(),
|
||||||
|
path: uri,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
mime: match ? match[1] : 'image/jpeg',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cropImage(img: ComposerImage): Promise<ComposerImage> {
|
||||||
|
if (!isNative) {
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE
|
||||||
|
// on ios, react-native-image-crop-picker gives really bad quality
|
||||||
|
// without specifying width and height. on android, however, the
|
||||||
|
// crop stretches incorrectly if you do specify it. these are
|
||||||
|
// both separate bugs in the library. we deal with that by
|
||||||
|
// providing width & height for ios only
|
||||||
|
// -prf
|
||||||
|
|
||||||
|
const source = img.source
|
||||||
|
const [w, h] = containImageRes(source.width, source.height, POST_IMG_MAX)
|
||||||
|
|
||||||
|
// @todo: we're always passing the original image here, does image-cropper
|
||||||
|
// allows for setting initial crop dimensions? -mary
|
||||||
|
try {
|
||||||
|
const cropped = await openCropper({
|
||||||
|
mediaType: 'photo',
|
||||||
|
path: source.path,
|
||||||
|
freeStyleCropEnabled: true,
|
||||||
|
...(isIOS ? {width: w, height: h} : {}),
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
alt: img.alt,
|
||||||
|
source: source,
|
||||||
|
transformed: {
|
||||||
|
path: await moveIfNecessary(cropped.path),
|
||||||
|
width: cropped.width,
|
||||||
|
height: cropped.height,
|
||||||
|
mime: cropped.mime,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof Error && e.message.includes('User cancelled')) {
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function manipulateImage(
|
||||||
|
img: ComposerImage,
|
||||||
|
trans: ImageTransformation,
|
||||||
|
): Promise<ComposerImage> {
|
||||||
|
const rawActions: (Action | undefined)[] = [trans.crop && {crop: trans.crop}]
|
||||||
|
|
||||||
|
const actions = rawActions.filter((a): a is Action => a !== undefined)
|
||||||
|
|
||||||
|
if (actions.length === 0) {
|
||||||
|
if (img.transformed === undefined) {
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
|
||||||
|
return {alt: img.alt, source: img.source}
|
||||||
|
}
|
||||||
|
|
||||||
|
const source = img.source
|
||||||
|
const result = await manipulateAsync(source.path, actions, {
|
||||||
|
format: SaveFormat.PNG,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
alt: img.alt,
|
||||||
|
source: img.source,
|
||||||
|
transformed: {
|
||||||
|
path: await moveIfNecessary(result.uri),
|
||||||
|
width: result.width,
|
||||||
|
height: result.height,
|
||||||
|
mime: 'image/png',
|
||||||
|
},
|
||||||
|
manips: trans,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetImageManipulation(
|
||||||
|
img: ComposerImage,
|
||||||
|
): ComposerImageWithoutTransformation {
|
||||||
|
if (img.transformed !== undefined) {
|
||||||
|
return {alt: img.alt, source: img.source}
|
||||||
|
}
|
||||||
|
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function compressImage(img: ComposerImage): Promise<ImageMeta> {
|
||||||
|
const source = img.transformed || img.source
|
||||||
|
|
||||||
|
const [w, h] = containImageRes(source.width, source.height, POST_IMG_MAX)
|
||||||
|
const cacheDir = isNative && getImageCacheDirectory()
|
||||||
|
|
||||||
|
for (let i = 10; i > 0; i--) {
|
||||||
|
// Float precision
|
||||||
|
const factor = i / 10
|
||||||
|
|
||||||
|
const res = await manipulateAsync(
|
||||||
|
source.path,
|
||||||
|
[{resize: {width: w, height: h}}],
|
||||||
|
{
|
||||||
|
compress: factor,
|
||||||
|
format: SaveFormat.JPEG,
|
||||||
|
base64: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const base64 = res.base64
|
||||||
|
|
||||||
|
if (base64 !== undefined && getDataUriSize(base64) <= POST_IMG_MAX.size) {
|
||||||
|
return {
|
||||||
|
path: await moveIfNecessary(res.uri),
|
||||||
|
width: res.width,
|
||||||
|
height: res.height,
|
||||||
|
mime: 'image/jpeg',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cacheDir) {
|
||||||
|
await deleteAsync(res.uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Unable to compress image`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function moveIfNecessary(from: string) {
|
||||||
|
const cacheDir = isNative && getImageCacheDirectory()
|
||||||
|
|
||||||
|
if (cacheDir && from.startsWith(cacheDir)) {
|
||||||
|
const to = joinPath(cacheDir, nanoid(36))
|
||||||
|
|
||||||
|
await makeDirectoryAsync(cacheDir, {intermediates: true})
|
||||||
|
await moveAsync({from, to})
|
||||||
|
|
||||||
|
return to
|
||||||
|
}
|
||||||
|
|
||||||
|
return from
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Purge files that were created to accomodate image manipulation */
|
||||||
|
export async function purgeTemporaryImageFiles() {
|
||||||
|
const cacheDir = isNative && getImageCacheDirectory()
|
||||||
|
|
||||||
|
if (cacheDir) {
|
||||||
|
await deleteAsync(cacheDir, {idempotent: true})
|
||||||
|
await makeDirectoryAsync(cacheDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function joinPath(a: string, b: string) {
|
||||||
|
if (a.endsWith('/')) {
|
||||||
|
if (b.startsWith('/')) {
|
||||||
|
return a.slice(0, -1) + b
|
||||||
|
}
|
||||||
|
return a + b
|
||||||
|
} else if (b.startsWith('/')) {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
return a + '/' + b
|
||||||
|
}
|
||||||
|
|
||||||
|
function containImageRes(
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
{width: maxW, height: maxH}: {width: number; height: number},
|
||||||
|
): [width: number, height: number] {
|
||||||
|
let scale = 1
|
||||||
|
|
||||||
|
if (w > maxW || h > maxH) {
|
||||||
|
scale = w > h ? maxW / w : maxH / h
|
||||||
|
w = Math.floor(w * scale)
|
||||||
|
h = Math.floor(h * scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
return [w, h]
|
||||||
|
}
|
||||||
@@ -3,8 +3,6 @@ import {Image as RNImage} from 'react-native-image-crop-picker'
|
|||||||
import {AppBskyActorDefs, AppBskyGraphDefs} from '@atproto/api'
|
import {AppBskyActorDefs, AppBskyGraphDefs} from '@atproto/api'
|
||||||
|
|
||||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||||
import {GalleryModel} from '#/state/models/media/gallery'
|
|
||||||
import {ImageModel} from '#/state/models/media/image'
|
|
||||||
|
|
||||||
export interface EditProfileModal {
|
export interface EditProfileModal {
|
||||||
name: 'edit-profile'
|
name: 'edit-profile'
|
||||||
@@ -37,24 +35,15 @@ export interface ListAddRemoveUsersModal {
|
|||||||
) => void
|
) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditImageModal {
|
|
||||||
name: 'edit-image'
|
|
||||||
image: ImageModel
|
|
||||||
gallery: GalleryModel
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CropImageModal {
|
export interface CropImageModal {
|
||||||
name: 'crop-image'
|
name: 'crop-image'
|
||||||
uri: string
|
uri: string
|
||||||
dimensions?: {width: number; height: number}
|
dimensions?: {width: number; height: number}
|
||||||
|
aspect?: number
|
||||||
|
circular?: boolean
|
||||||
onSelect: (img?: RNImage) => void
|
onSelect: (img?: RNImage) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AltTextImageModal {
|
|
||||||
name: 'alt-text-image'
|
|
||||||
image: ImageModel
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DeleteAccountModal {
|
export interface DeleteAccountModal {
|
||||||
name: 'delete-account'
|
name: 'delete-account'
|
||||||
}
|
}
|
||||||
@@ -137,9 +126,7 @@ export type Modal =
|
|||||||
| ListAddRemoveUsersModal
|
| ListAddRemoveUsersModal
|
||||||
|
|
||||||
// Posts
|
// Posts
|
||||||
| AltTextImageModal
|
|
||||||
| CropImageModal
|
| CropImageModal
|
||||||
| EditImageModal
|
|
||||||
| SelfLabelModal
|
| SelfLabelModal
|
||||||
|
|
||||||
// Bluesky access
|
// Bluesky access
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
import {makeAutoObservable, runInAction} from 'mobx'
|
|
||||||
|
|
||||||
import {getImageDim} from 'lib/media/manip'
|
|
||||||
import {openPicker} from 'lib/media/picker'
|
|
||||||
import {ImageInitOptions, ImageModel} from './image'
|
|
||||||
|
|
||||||
interface InitialImageUri {
|
|
||||||
uri: string
|
|
||||||
width: number
|
|
||||||
height: number
|
|
||||||
altText?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export class GalleryModel {
|
|
||||||
images: ImageModel[] = []
|
|
||||||
|
|
||||||
constructor(uris?: InitialImageUri[]) {
|
|
||||||
makeAutoObservable(this)
|
|
||||||
|
|
||||||
if (uris) {
|
|
||||||
this.addFromUris(uris)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get isEmpty() {
|
|
||||||
return this.size === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
get size() {
|
|
||||||
return this.images.length
|
|
||||||
}
|
|
||||||
|
|
||||||
get needsAltText() {
|
|
||||||
return this.images.some(image => image.altText.trim() === '')
|
|
||||||
}
|
|
||||||
|
|
||||||
*add(image_: ImageInitOptions) {
|
|
||||||
if (this.size >= 4) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temporarily enforce uniqueness but can eventually also use index
|
|
||||||
if (!this.images.some(i => i.path === image_.path)) {
|
|
||||||
const image = new ImageModel(image_)
|
|
||||||
|
|
||||||
// Initial resize
|
|
||||||
image.manipulate({})
|
|
||||||
this.images.push(image)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async paste(uri: string) {
|
|
||||||
if (this.size >= 4) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const {width, height} = await getImageDim(uri)
|
|
||||||
|
|
||||||
const image = {
|
|
||||||
path: uri,
|
|
||||||
height,
|
|
||||||
width,
|
|
||||||
}
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
this.add(image)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
setAltText(image: ImageModel, altText: string) {
|
|
||||||
image.setAltText(altText)
|
|
||||||
}
|
|
||||||
|
|
||||||
crop(image: ImageModel) {
|
|
||||||
image.crop()
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(image: ImageModel) {
|
|
||||||
const index = this.images.findIndex(image_ => image_.path === image.path)
|
|
||||||
this.images.splice(index, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
async previous(image: ImageModel) {
|
|
||||||
image.previous()
|
|
||||||
}
|
|
||||||
|
|
||||||
async pick() {
|
|
||||||
const images = await openPicker({
|
|
||||||
selectionLimit: 4 - this.size,
|
|
||||||
allowsMultipleSelection: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
return await Promise.all(
|
|
||||||
images.map(image => {
|
|
||||||
this.add(image)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
async addFromUris(uris: InitialImageUri[]) {
|
|
||||||
for (const uriObj of uris) {
|
|
||||||
this.add({
|
|
||||||
height: uriObj.height,
|
|
||||||
width: uriObj.width,
|
|
||||||
path: uriObj.uri,
|
|
||||||
altText: uriObj.altText,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
import {Image as RNImage} from 'react-native-image-crop-picker'
|
|
||||||
import {makeAutoObservable} from 'mobx'
|
|
||||||
import {POST_IMG_MAX} from 'lib/constants'
|
|
||||||
import {ActionCrop} from 'expo-image-manipulator'
|
|
||||||
import {Position} from 'react-avatar-editor'
|
|
||||||
import {Dimensions} from 'lib/media/types'
|
|
||||||
|
|
||||||
export interface ImageManipulationAttributes {
|
|
||||||
aspectRatio?: '4:3' | '1:1' | '3:4' | 'None'
|
|
||||||
rotate?: number
|
|
||||||
scale?: number
|
|
||||||
position?: Position
|
|
||||||
flipHorizontal?: boolean
|
|
||||||
flipVertical?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ImageModel implements Omit<RNImage, 'size'> {
|
|
||||||
path: string
|
|
||||||
mime = 'image/jpeg'
|
|
||||||
width: number
|
|
||||||
height: number
|
|
||||||
altText = ''
|
|
||||||
cropped?: RNImage = undefined
|
|
||||||
compressed?: RNImage = undefined
|
|
||||||
|
|
||||||
// Web manipulation
|
|
||||||
prev?: RNImage
|
|
||||||
attributes: ImageManipulationAttributes = {
|
|
||||||
aspectRatio: 'None',
|
|
||||||
scale: 1,
|
|
||||||
flipHorizontal: false,
|
|
||||||
flipVertical: false,
|
|
||||||
rotate: 0,
|
|
||||||
}
|
|
||||||
prevAttributes: ImageManipulationAttributes = {}
|
|
||||||
|
|
||||||
constructor(image: Omit<RNImage, 'size'>) {
|
|
||||||
makeAutoObservable(this)
|
|
||||||
|
|
||||||
this.path = image.path
|
|
||||||
this.width = image.width
|
|
||||||
this.height = image.height
|
|
||||||
}
|
|
||||||
|
|
||||||
setRatio(aspectRatio: ImageManipulationAttributes['aspectRatio']) {
|
|
||||||
this.attributes.aspectRatio = aspectRatio
|
|
||||||
}
|
|
||||||
|
|
||||||
setRotate(degrees: number) {
|
|
||||||
this.attributes.rotate = degrees
|
|
||||||
this.manipulate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
flipVertical() {
|
|
||||||
this.attributes.flipVertical = !this.attributes.flipVertical
|
|
||||||
this.manipulate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
flipHorizontal() {
|
|
||||||
this.attributes.flipHorizontal = !this.attributes.flipHorizontal
|
|
||||||
this.manipulate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
get ratioMultipliers() {
|
|
||||||
return {
|
|
||||||
'4:3': 4 / 3,
|
|
||||||
'1:1': 1,
|
|
||||||
'3:4': 3 / 4,
|
|
||||||
None: this.width / this.height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getUploadDimensions(
|
|
||||||
dimensions: Dimensions,
|
|
||||||
maxDimensions: Dimensions = POST_IMG_MAX,
|
|
||||||
as: ImageManipulationAttributes['aspectRatio'] = 'None',
|
|
||||||
) {
|
|
||||||
const {width, height} = dimensions
|
|
||||||
const {width: maxWidth, height: maxHeight} = maxDimensions
|
|
||||||
|
|
||||||
return width < maxWidth && height < maxHeight
|
|
||||||
? {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
}
|
|
||||||
: this.getResizedDimensions(as, POST_IMG_MAX.width)
|
|
||||||
}
|
|
||||||
|
|
||||||
getResizedDimensions(
|
|
||||||
as: ImageManipulationAttributes['aspectRatio'] = 'None',
|
|
||||||
maxSide: number,
|
|
||||||
) {
|
|
||||||
const ratioMultiplier = this.ratioMultipliers[as]
|
|
||||||
|
|
||||||
if (ratioMultiplier === 1) {
|
|
||||||
return {
|
|
||||||
height: maxSide,
|
|
||||||
width: maxSide,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ratioMultiplier < 1) {
|
|
||||||
return {
|
|
||||||
width: maxSide * ratioMultiplier,
|
|
||||||
height: maxSide,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
width: maxSide,
|
|
||||||
height: maxSide / ratioMultiplier,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAltText(altText: string) {
|
|
||||||
this.altText = altText.trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only compress prior to upload
|
|
||||||
async compress() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mobile
|
|
||||||
async crop() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
// Web manipulation
|
|
||||||
async manipulate(
|
|
||||||
_attributes: {
|
|
||||||
crop?: ActionCrop['crop']
|
|
||||||
} & ImageManipulationAttributes,
|
|
||||||
) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
resetCropped() {
|
|
||||||
this.manipulate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
previous() {
|
|
||||||
this.cropped = this.prev
|
|
||||||
this.attributes = this.prevAttributes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,310 +0,0 @@
|
|||||||
import {Image as RNImage} from 'react-native-image-crop-picker'
|
|
||||||
import * as ImageManipulator from 'expo-image-manipulator'
|
|
||||||
import {ActionCrop, FlipType, SaveFormat} from 'expo-image-manipulator'
|
|
||||||
import {makeAutoObservable, runInAction} from 'mobx'
|
|
||||||
import {Position} from 'react-avatar-editor'
|
|
||||||
|
|
||||||
import {logger} from '#/logger'
|
|
||||||
import {POST_IMG_MAX} from 'lib/constants'
|
|
||||||
import {openCropper} from 'lib/media/picker'
|
|
||||||
import {Dimensions} from 'lib/media/types'
|
|
||||||
import {getDataUriSize} from 'lib/media/util'
|
|
||||||
import {isIOS} from 'platform/detection'
|
|
||||||
|
|
||||||
export interface ImageManipulationAttributes {
|
|
||||||
aspectRatio?: '4:3' | '1:1' | '3:4' | 'None'
|
|
||||||
rotate?: number
|
|
||||||
scale?: number
|
|
||||||
position?: Position
|
|
||||||
flipHorizontal?: boolean
|
|
||||||
flipVertical?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ImageInitOptions {
|
|
||||||
path: string
|
|
||||||
width: number
|
|
||||||
height: number
|
|
||||||
altText?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const MAX_IMAGE_SIZE_IN_BYTES = 976560
|
|
||||||
|
|
||||||
export class ImageModel implements Omit<RNImage, 'size'> {
|
|
||||||
path: string
|
|
||||||
mime = 'image/jpeg'
|
|
||||||
width: number
|
|
||||||
height: number
|
|
||||||
altText = ''
|
|
||||||
cropped?: RNImage = undefined
|
|
||||||
compressed?: RNImage = undefined
|
|
||||||
|
|
||||||
// Web manipulation
|
|
||||||
prev?: RNImage
|
|
||||||
attributes: ImageManipulationAttributes = {
|
|
||||||
aspectRatio: 'None',
|
|
||||||
scale: 1,
|
|
||||||
flipHorizontal: false,
|
|
||||||
flipVertical: false,
|
|
||||||
rotate: 0,
|
|
||||||
}
|
|
||||||
prevAttributes: ImageManipulationAttributes = {}
|
|
||||||
|
|
||||||
constructor(image: ImageInitOptions) {
|
|
||||||
makeAutoObservable(this)
|
|
||||||
|
|
||||||
this.path = image.path
|
|
||||||
this.width = image.width
|
|
||||||
this.height = image.height
|
|
||||||
if (image.altText !== undefined) {
|
|
||||||
this.setAltText(image.altText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setRatio(aspectRatio: ImageManipulationAttributes['aspectRatio']) {
|
|
||||||
this.attributes.aspectRatio = aspectRatio
|
|
||||||
}
|
|
||||||
|
|
||||||
setRotate(degrees: number) {
|
|
||||||
this.attributes.rotate = degrees
|
|
||||||
this.manipulate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
flipVertical() {
|
|
||||||
this.attributes.flipVertical = !this.attributes.flipVertical
|
|
||||||
this.manipulate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
flipHorizontal() {
|
|
||||||
this.attributes.flipHorizontal = !this.attributes.flipHorizontal
|
|
||||||
this.manipulate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
get ratioMultipliers() {
|
|
||||||
return {
|
|
||||||
'4:3': 4 / 3,
|
|
||||||
'1:1': 1,
|
|
||||||
'3:4': 3 / 4,
|
|
||||||
None: this.width / this.height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getUploadDimensions(
|
|
||||||
dimensions: Dimensions,
|
|
||||||
maxDimensions: Dimensions = POST_IMG_MAX,
|
|
||||||
as: ImageManipulationAttributes['aspectRatio'] = 'None',
|
|
||||||
) {
|
|
||||||
const {width, height} = dimensions
|
|
||||||
const {width: maxWidth, height: maxHeight} = maxDimensions
|
|
||||||
|
|
||||||
return width < maxWidth && height < maxHeight
|
|
||||||
? {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
}
|
|
||||||
: this.getResizedDimensions(as, POST_IMG_MAX.width)
|
|
||||||
}
|
|
||||||
|
|
||||||
getResizedDimensions(
|
|
||||||
as: ImageManipulationAttributes['aspectRatio'] = 'None',
|
|
||||||
maxSide: number,
|
|
||||||
) {
|
|
||||||
const ratioMultiplier = this.ratioMultipliers[as]
|
|
||||||
|
|
||||||
if (ratioMultiplier === 1) {
|
|
||||||
return {
|
|
||||||
height: maxSide,
|
|
||||||
width: maxSide,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ratioMultiplier < 1) {
|
|
||||||
return {
|
|
||||||
width: maxSide * ratioMultiplier,
|
|
||||||
height: maxSide,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
width: maxSide,
|
|
||||||
height: maxSide / ratioMultiplier,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAltText(altText: string) {
|
|
||||||
this.altText = altText.trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only compress prior to upload
|
|
||||||
async compress() {
|
|
||||||
for (let i = 10; i > 0; i--) {
|
|
||||||
// Float precision
|
|
||||||
const factor = Math.round(i) / 10
|
|
||||||
const compressed = await ImageManipulator.manipulateAsync(
|
|
||||||
this.cropped?.path ?? this.path,
|
|
||||||
undefined,
|
|
||||||
{
|
|
||||||
compress: factor,
|
|
||||||
base64: true,
|
|
||||||
format: SaveFormat.JPEG,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if (compressed.base64 !== undefined) {
|
|
||||||
const size = getDataUriSize(compressed.base64)
|
|
||||||
|
|
||||||
if (size < MAX_IMAGE_SIZE_IN_BYTES) {
|
|
||||||
runInAction(() => {
|
|
||||||
this.compressed = {
|
|
||||||
mime: 'image/jpeg',
|
|
||||||
path: compressed.uri,
|
|
||||||
size,
|
|
||||||
...compressed,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compression fails when removing redundant information is not possible.
|
|
||||||
// This can be tested with images that have high variance in noise.
|
|
||||||
throw new Error('Failed to compress image')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mobile
|
|
||||||
async crop() {
|
|
||||||
try {
|
|
||||||
// NOTE
|
|
||||||
// on ios, react-native-image-crop-picker gives really bad quality
|
|
||||||
// without specifying width and height. on android, however, the
|
|
||||||
// crop stretches incorrectly if you do specify it. these are
|
|
||||||
// both separate bugs in the library. we deal with that by
|
|
||||||
// providing width & height for ios only
|
|
||||||
// -prf
|
|
||||||
const {width, height} = this.getUploadDimensions({
|
|
||||||
width: this.width,
|
|
||||||
height: this.height,
|
|
||||||
})
|
|
||||||
|
|
||||||
const cropped = await openCropper({
|
|
||||||
mediaType: 'photo',
|
|
||||||
path: this.path,
|
|
||||||
freeStyleCropEnabled: true,
|
|
||||||
...(isIOS ? {width, height} : {}),
|
|
||||||
})
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
this.cropped = cropped
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
logger.error('Failed to crop photo', {message: err})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Web manipulation
|
|
||||||
async manipulate(
|
|
||||||
attributes: {
|
|
||||||
crop?: ActionCrop['crop']
|
|
||||||
} & ImageManipulationAttributes,
|
|
||||||
) {
|
|
||||||
let uploadWidth: number | undefined
|
|
||||||
let uploadHeight: number | undefined
|
|
||||||
|
|
||||||
const {aspectRatio, crop, position, scale} = attributes
|
|
||||||
const modifiers = []
|
|
||||||
|
|
||||||
if (this.attributes.flipHorizontal) {
|
|
||||||
modifiers.push({flip: FlipType.Horizontal})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.attributes.flipVertical) {
|
|
||||||
modifiers.push({flip: FlipType.Vertical})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.attributes.rotate !== undefined) {
|
|
||||||
modifiers.push({rotate: this.attributes.rotate})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crop !== undefined) {
|
|
||||||
const croppedHeight = crop.height * this.height
|
|
||||||
const croppedWidth = crop.width * this.width
|
|
||||||
modifiers.push({
|
|
||||||
crop: {
|
|
||||||
originX: crop.originX * this.width,
|
|
||||||
originY: crop.originY * this.height,
|
|
||||||
height: croppedHeight,
|
|
||||||
width: croppedWidth,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const uploadDimensions = this.getUploadDimensions(
|
|
||||||
{width: croppedWidth, height: croppedHeight},
|
|
||||||
POST_IMG_MAX,
|
|
||||||
aspectRatio,
|
|
||||||
)
|
|
||||||
|
|
||||||
uploadWidth = uploadDimensions.width
|
|
||||||
uploadHeight = uploadDimensions.height
|
|
||||||
} else {
|
|
||||||
const uploadDimensions = this.getUploadDimensions(
|
|
||||||
{width: this.width, height: this.height},
|
|
||||||
POST_IMG_MAX,
|
|
||||||
aspectRatio,
|
|
||||||
)
|
|
||||||
|
|
||||||
uploadWidth = uploadDimensions.width
|
|
||||||
uploadHeight = uploadDimensions.height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scale !== undefined) {
|
|
||||||
this.attributes.scale = scale
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position !== undefined) {
|
|
||||||
this.attributes.position = position
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aspectRatio !== undefined) {
|
|
||||||
this.attributes.aspectRatio = aspectRatio
|
|
||||||
}
|
|
||||||
|
|
||||||
const ratioMultiplier =
|
|
||||||
this.ratioMultipliers[this.attributes.aspectRatio ?? '1:1']
|
|
||||||
|
|
||||||
const result = await ImageManipulator.manipulateAsync(
|
|
||||||
this.path,
|
|
||||||
[
|
|
||||||
...modifiers,
|
|
||||||
{
|
|
||||||
resize:
|
|
||||||
ratioMultiplier > 1 ? {width: uploadWidth} : {height: uploadHeight},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
{
|
|
||||||
base64: true,
|
|
||||||
format: SaveFormat.JPEG,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
this.cropped = {
|
|
||||||
mime: 'image/jpeg',
|
|
||||||
path: result.uri,
|
|
||||||
size:
|
|
||||||
result.base64 !== undefined
|
|
||||||
? getDataUriSize(result.base64)
|
|
||||||
: MAX_IMAGE_SIZE_IN_BYTES + 999, // shouldn't hit this unless manipulation fails
|
|
||||||
...result,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
resetCropped() {
|
|
||||||
this.manipulate({})
|
|
||||||
}
|
|
||||||
|
|
||||||
previous() {
|
|
||||||
this.cropped = this.prev
|
|
||||||
this.attributes = this.prevAttributes
|
|
||||||
}
|
|
||||||
}
|
|
||||||