shared-ritm 1.2.80 → 1.2.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +103 -103
  2. package/dist/index.css +1 -1
  3. package/dist/shared-ritm.es.js +9409 -8849
  4. package/dist/shared-ritm.umd.js +520 -520
  5. package/dist/types/api/services/UserService.d.ts +10 -1
  6. package/dist/types/api/types/Api_Service.d.ts +1 -1
  7. package/dist/types/api/types/Api_User.d.ts +11 -0
  8. package/dist/types/common/app-table/controllers/useTableModel.d.ts +1 -1
  9. package/dist/types/index.d.ts +41 -40
  10. package/package.json +64 -64
  11. package/src/api/services/PhotoService.ts +137 -137
  12. package/src/api/services/RepairsService.ts +119 -119
  13. package/src/api/services/UserService.ts +32 -19
  14. package/src/api/types/Api_Controls.ts +72 -72
  15. package/src/api/types/Api_Files.ts +1 -1
  16. package/src/api/types/Api_Instruments.ts +98 -98
  17. package/src/api/types/Api_Projects.ts +55 -55
  18. package/src/api/types/Api_Repairs.ts +115 -115
  19. package/src/api/types/Api_Service.ts +1 -1
  20. package/src/api/types/Api_User.ts +57 -44
  21. package/src/common/app-checkbox/AppCheckbox.vue +26 -26
  22. package/src/common/app-datepicker/AppDatepicker.vue +165 -165
  23. package/src/common/app-dialogs/AppConfirmDialog.vue +99 -99
  24. package/src/common/app-dropdown/AppDropdown.vue +31 -31
  25. package/src/common/app-input/AppInput.vue +148 -148
  26. package/src/common/app-input-new/AppInputNew.vue +152 -152
  27. package/src/common/app-select/AppSelect.vue +157 -157
  28. package/src/common/app-sheet/AppSheet.vue +120 -120
  29. package/src/common/app-sheet-new/AppSheetNew.vue +255 -0
  30. package/src/common/app-sidebar/components/SidebarMenuItem.vue +148 -148
  31. package/src/common/app-table/AppTable.vue +301 -297
  32. package/src/common/app-table/AppTableLayout.vue +126 -111
  33. package/src/common/app-table/components/ModalSelect.vue +270 -270
  34. package/src/common/app-table/components/TableModal.vue +329 -329
  35. package/src/common/app-table/components/TablePagination.vue +152 -152
  36. package/src/common/app-table/components/TableSearch.vue +76 -76
  37. package/src/common/app-table/controllers/useBaseTable.ts +42 -42
  38. package/src/common/app-table/controllers/useColumnSelector.ts +38 -38
  39. package/src/common/app-table/controllers/useTableModel.ts +93 -93
  40. package/src/common/app-toggle/AppToggle.vue +24 -24
  41. package/src/common/app-wrapper/AppWrapper.vue +28 -28
  42. package/src/icons/components/table-filter-icon.vue +30 -30
  43. package/src/icons/dialogs/RemoveIcon.vue +12 -12
  44. package/src/icons/dialogs/SafetyIcon.vue +12 -12
  45. package/src/icons/task/attention-icon.vue +13 -13
  46. package/src/icons/task/clock-icon.vue +10 -10
  47. package/src/icons/task/delete-icon.vue +10 -10
  48. package/src/icons/task/fire-icon.vue +16 -16
  49. package/src/index.ts +41 -39
  50. package/src/main.ts +28 -28
  51. package/src/shared/styles/general.css +125 -125
  52. package/src/styles/variables.sass +12 -12
  53. package/src/utils/confirm.ts +12 -12
  54. package/src/utils/helpers.ts +58 -58
  55. package/src/utils/notification.ts +9 -9
  56. package/dist/types/api/types/Api_Users.d.ts +0 -43
@@ -1,11 +1,20 @@
1
1
  import ApiService from '@/api/settings/ApiService';
2
- import { Api_User } from '@/api/types/Api_User';
2
+ import { Api_User, Api_User_Role } from '@/api/types/Api_User';
3
+ import { ResponseApi } from '@/api/types/Api_Service';
3
4
  declare class UserService extends ApiService {
4
5
  editUser({ id, model }: {
5
6
  id: string;
6
7
  model: any;
7
8
  }): Promise<Api_User>;
8
9
  getUser(id: string): Promise<Api_User>;
10
+ createUser(model: Partial<Api_User>): Promise<Api_User>;
11
+ deleteUser(id: string): Promise<{
12
+ data: boolean;
13
+ status: number;
14
+ }>;
15
+ getRoles(params?: {
16
+ per_page?: number;
17
+ }): Promise<ResponseApi<Api_User_Role[]>>;
9
18
  }
10
19
  export default function useUserService(): UserService;
11
20
  export {};
@@ -5,5 +5,5 @@ export type ResponseApi<T> = {
5
5
  per_page: number;
6
6
  total: number;
7
7
  total_pages: number;
8
- filter_value?: string;
8
+ filter_value?: Record<string, any[]>;
9
9
  };
@@ -40,3 +40,14 @@ export type Api_User = {
40
40
  teams: Api_User_Team[];
41
41
  photos: Api_User_Photo[];
42
42
  };
43
+ export type Api_User_Permission = {
44
+ id: string;
45
+ name: string;
46
+ display_name: string;
47
+ };
48
+ export type Api_User_Role = {
49
+ id: string;
50
+ name: string;
51
+ display_name: string;
52
+ permissions?: Api_User_Permission[];
53
+ };
@@ -4,7 +4,7 @@ export interface TableColumn {
4
4
  label: string;
5
5
  style?: string;
6
6
  headerStyle?: string;
7
- field: string | ((row: any) => any);
7
+ field?: string | ((row: any) => any);
8
8
  sortable?: boolean;
9
9
  filterType?: 'single' | 'multi' | null;
10
10
  align?: 'left' | 'center' | 'right';
@@ -1,43 +1,44 @@
1
- import './shared/styles/general.css';
2
- import AppButton from './common/app-button/AppButton.vue';
3
- import AppCheckbox from './common/app-checkbox/AppCheckbox.vue';
4
- import AppDatePicker from './common/app-date-picker/AppDatePicker.vue';
5
- import AppDatepicker from './common/app-datepicker/AppDatepicker.vue';
6
- import AppInput from './common/app-input/AppInput.vue';
7
- import AppInputNew from './common/app-input-new/AppInputNew.vue';
8
- import AppInputSearch from './common/app-input-search/AppInputSearch.vue';
9
- import AppLayout from './common/app-layout/AppLayout.vue';
10
- import AppLayoutHeader from './common/app-layout/components/AppLayoutHeader.vue';
11
- import AppLayoutPage from './common/app-layout/components/AppLayoutPage.vue';
12
- import AppLoader from './common/app-loader/index.vue';
13
- import AppSelect from './common/app-select/AppSelect.vue';
14
- import AppSheet from './common/app-sheet/AppSheet.vue';
15
- import AppSidebar from './common/app-sidebar/AppSidebar.vue';
16
- import AppToggle from './common/app-toggle/AppToggle.vue';
17
- import AppWrapper from './common/app-wrapper/AppWrapper.vue';
18
- import AppConfirmDialog from './common/app-dialogs/AppConfirmDialog.vue';
19
- import AppDropdown from './common/app-dropdown/AppDropdown.vue';
20
- import AppTablePagination from './common/app-table/components/TablePagination.vue';
21
- import AppTableSearch from './common/app-table/components/TableSearch.vue';
22
- import AppTableModal from './common/app-table/components/TableModal.vue';
23
- import AppTable from './common/app-table/AppTable.vue';
24
- import AppTableLayout from './common/app-table/AppTableLayout.vue';
25
- import AppModalSelect from './common/app-table/components/ModalSelect.vue';
26
- import ApiService from './api/settings/ApiService';
27
- import useGanttService from './api/services/GanttService';
28
- import useMetricsService from './api/services/MetricsService';
29
- import useProjectsService from './api/services/ProjectsService';
30
- import useRepairsService from './api/services/RepairsService';
31
- import useTasksService from './api/services/TasksService';
32
- import useAuthService from './api/services/AuthService';
33
- import useFileService from './api/services/FileService';
34
- import useVideoService from './api/services/VideoService';
35
- import useUserService from './api/services/UserService';
36
- import usePhotoService from './api/services/PhotoService';
37
- import useInstrumentsService from './api/services/InstrumentsService';
38
- import useControlsService from './api/services/ControlsService';
39
- import useSearchService from './api/services/SearchService';
40
- export { AppButton, AppCheckbox, AppDatepicker, AppDatePicker, AppInput, AppInputNew, AppInputSearch, AppLayout, AppLayoutHeader, AppLayoutPage, AppLoader, AppSelect, AppSheet, AppSidebar, AppToggle, AppWrapper, AppConfirmDialog, AppDropdown, AppTablePagination, AppTableSearch, AppTableModal, AppTable, AppTableLayout, AppModalSelect, };
1
+ import '@/shared/styles/general.css';
2
+ import AppButton from '@/common/app-button/AppButton.vue';
3
+ import AppCheckbox from '@/common/app-checkbox/AppCheckbox.vue';
4
+ import AppDatePicker from '@/common/app-date-picker/AppDatePicker.vue';
5
+ import AppDatepicker from '@/common/app-datepicker/AppDatepicker.vue';
6
+ import AppInput from '@/common/app-input/AppInput.vue';
7
+ import AppInputNew from '@/common/app-input-new/AppInputNew.vue';
8
+ import AppInputSearch from '@/common/app-input-search/AppInputSearch.vue';
9
+ import AppLayout from '@/common/app-layout/AppLayout.vue';
10
+ import AppLayoutHeader from '@/common/app-layout/components/AppLayoutHeader.vue';
11
+ import AppLayoutPage from '@/common/app-layout/components/AppLayoutPage.vue';
12
+ import AppLoader from '@/common/app-loader/index.vue';
13
+ import AppSelect from '@/common/app-select/AppSelect.vue';
14
+ import AppSheet from '@/common/app-sheet/AppSheet.vue';
15
+ import AppSheetNew from '@/common/app-sheet-new/AppSheetNew.vue';
16
+ import AppSidebar from '@/common/app-sidebar/AppSidebar.vue';
17
+ import AppToggle from '@/common/app-toggle/AppToggle.vue';
18
+ import AppWrapper from '@/common/app-wrapper/AppWrapper.vue';
19
+ import AppConfirmDialog from '@/common/app-dialogs/AppConfirmDialog.vue';
20
+ import AppDropdown from '@/common/app-dropdown/AppDropdown.vue';
21
+ import AppTablePagination from '@/common/app-table/components/TablePagination.vue';
22
+ import AppTableSearch from '@/common/app-table/components/TableSearch.vue';
23
+ import AppTableModal from '@/common/app-table/components/TableModal.vue';
24
+ import AppTable from '@/common/app-table/AppTable.vue';
25
+ import AppTableLayout from '@/common/app-table/AppTableLayout.vue';
26
+ import AppModalSelect from '@/common/app-table/components/ModalSelect.vue';
27
+ import ApiService from '@/api/settings/ApiService';
28
+ import useGanttService from '@/api/services/GanttService';
29
+ import useMetricsService from '@/api/services/MetricsService';
30
+ import useProjectsService from '@/api/services/ProjectsService';
31
+ import useRepairsService from '@/api/services/RepairsService';
32
+ import useTasksService from '@/api/services/TasksService';
33
+ import useAuthService from '@/api/services/AuthService';
34
+ import useFileService from '@/api/services/FileService';
35
+ import useVideoService from '@/api/services/VideoService';
36
+ import useUserService from '@/api/services/UserService';
37
+ import usePhotoService from '@/api/services/PhotoService';
38
+ import useInstrumentsService from '@/api/services/InstrumentsService';
39
+ import useControlsService from '@/api/services/ControlsService';
40
+ import useSearchService from '@/api/services/SearchService';
41
+ export { AppButton, AppCheckbox, AppDatepicker, AppDatePicker, AppInput, AppInputNew, AppInputSearch, AppLayout, AppLayoutHeader, AppLayoutPage, AppLoader, AppSelect, AppSheet, AppSheetNew, AppSidebar, AppToggle, AppWrapper, AppConfirmDialog, AppDropdown, AppTablePagination, AppTableSearch, AppTableModal, AppTable, AppTableLayout, AppModalSelect, };
41
42
  export { ApiService, useAuthService, useGanttService, useMetricsService, useProjectsService, useRepairsService, useTasksService, useFileService, useControlsService, useVideoService, useUserService, usePhotoService, useInstrumentsService, useSearchService, };
42
43
  export { useBaseTable } from './common/app-table/controllers/useBaseTable';
43
44
  export { useTableModel } from './common/app-table/controllers/useTableModel';
package/package.json CHANGED
@@ -1,64 +1,64 @@
1
- {
2
- "name": "shared-ritm",
3
- "version": "1.2.80",
4
- "private": false,
5
- "files": [
6
- "dist",
7
- "src"
8
- ],
9
- "main": "dist/shared-ritm.umd.js",
10
- "type": "module",
11
- "module": "./dist/shared-ritm.es.js",
12
- "types": "./dist/types/index.d.ts",
13
- "exports": {
14
- ".": {
15
- "import": "./dist/shared-ritm.es.js",
16
- "require": "./dist/shared-ritm.umd.js",
17
- "default": "./dist/shared-ritm.es.js",
18
- "types": "./dist/types/index.d.ts"
19
- },
20
- "./style": "./dist/index.css"
21
- },
22
- "scripts": {
23
- "dev": "vite",
24
- "build": "vite build && tsc --emitDeclarationOnly",
25
- "typecheck": "vue-tsc --noEmit",
26
- "lint": "eslint --fix",
27
- "format": "prettier -w -u ."
28
- },
29
- "dependencies": {
30
- "@quasar/extras": "^1.16.17",
31
- "@vueuse/core": "^10.1.2",
32
- "face-api.js": "^0.22.2",
33
- "axios": "^1.7.7",
34
- "vue": "^3.5.12",
35
- "vue-router": "^4.0.3"
36
- },
37
- "peerDependencies": {
38
- "quasar": "^2.18.1"
39
- },
40
- "devDependencies": {
41
- "@quasar/vite-plugin": "^1.9.0",
42
- "@rollup/pluginutils": "^5.1.3",
43
- "@types/node": "^22.7.9",
44
- "@typescript-eslint/eslint-plugin": "^4.25.0",
45
- "@typescript-eslint/parser": "^4.25.0",
46
- "@vitejs/plugin-vue": "^5.1.4",
47
- "@vue/compiler-sfc": "^3.0.5",
48
- "@vue/eslint-config-prettier": "^6.0.0",
49
- "@vue/eslint-config-typescript": "^7.0.0",
50
- "eslint": "^7.27.0",
51
- "eslint-plugin-prettier": "^3.4.0",
52
- "eslint-plugin-vue": "^7.10.0",
53
- "install": "^0.13.0",
54
- "npm": "^11.4.0",
55
- "prettier": "^2.3.0",
56
- "quasar": "^2.18.1",
57
- "rollup-plugin-visualizer": "^5.14.0",
58
- "sass": "^1.80.4",
59
- "typescript": "^5.6.3",
60
- "vite": "^5.4.9",
61
- "vite-plugin-css-modules": "^0.0.1",
62
- "vue-tsc": "^2.1.6"
63
- }
64
- }
1
+ {
2
+ "name": "shared-ritm",
3
+ "version": "1.2.81",
4
+ "private": false,
5
+ "files": [
6
+ "dist",
7
+ "src"
8
+ ],
9
+ "main": "dist/shared-ritm.umd.js",
10
+ "type": "module",
11
+ "module": "./dist/shared-ritm.es.js",
12
+ "types": "./dist/types/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/shared-ritm.es.js",
16
+ "require": "./dist/shared-ritm.umd.js",
17
+ "default": "./dist/shared-ritm.es.js",
18
+ "types": "./dist/types/index.d.ts"
19
+ },
20
+ "./style": "./dist/index.css"
21
+ },
22
+ "scripts": {
23
+ "dev": "vite",
24
+ "build": "vite build && tsc --emitDeclarationOnly",
25
+ "typecheck": "vue-tsc --noEmit",
26
+ "lint": "eslint --fix",
27
+ "format": "prettier -w -u ."
28
+ },
29
+ "dependencies": {
30
+ "@quasar/extras": "^1.16.17",
31
+ "@vueuse/core": "^10.1.2",
32
+ "face-api.js": "^0.22.2",
33
+ "axios": "^1.7.7",
34
+ "vue": "^3.5.12",
35
+ "vue-router": "^4.0.3"
36
+ },
37
+ "peerDependencies": {
38
+ "quasar": "^2.18.1"
39
+ },
40
+ "devDependencies": {
41
+ "@quasar/vite-plugin": "^1.9.0",
42
+ "@rollup/pluginutils": "^5.1.3",
43
+ "@types/node": "^22.7.9",
44
+ "@typescript-eslint/eslint-plugin": "^4.25.0",
45
+ "@typescript-eslint/parser": "^4.25.0",
46
+ "@vitejs/plugin-vue": "^5.1.4",
47
+ "@vue/compiler-sfc": "^3.0.5",
48
+ "@vue/eslint-config-prettier": "^6.0.0",
49
+ "@vue/eslint-config-typescript": "^7.0.0",
50
+ "eslint": "^7.27.0",
51
+ "eslint-plugin-prettier": "^3.4.0",
52
+ "eslint-plugin-vue": "^7.10.0",
53
+ "install": "^0.13.0",
54
+ "npm": "^11.4.0",
55
+ "prettier": "^2.3.0",
56
+ "quasar": "^2.18.1",
57
+ "rollup-plugin-visualizer": "^5.14.0",
58
+ "sass": "^1.80.4",
59
+ "typescript": "^5.6.3",
60
+ "vite": "^5.4.9",
61
+ "vite-plugin-css-modules": "^0.0.1",
62
+ "vue-tsc": "^2.1.6"
63
+ }
64
+ }
@@ -1,137 +1,137 @@
1
- import * as faceapi from 'face-api.js'
2
-
3
- class PhotoService {
4
- // async getFaceSnapshot(inputImage: any, box: any) {
5
- // const regionsToExtract = [new faceapi.Rect(box.x, box.y, box.width, box.height)]
6
- // const faceImages = await faceapi.extractFaces(inputImage, regionsToExtract)
7
- // if (faceImages.length) {
8
- // const dataUrl = faceImages[0].toDataURL('image/jpeg')
9
- // photo.value = dataUrl.replace(/^data:image\/\w+;base64,/, '')
10
- // }
11
- // }
12
-
13
- // Метод настройки конфига для стрима
14
- getVideoStreamConfig(width: number, height: number) {
15
- return {
16
- audio: false,
17
- video: {
18
- width: { min: width, ideal: width },
19
- height: { min: height, ideal: height },
20
- facingMode: 'environment', // или 'user' для фронтальной камеры
21
- },
22
- }
23
- }
24
-
25
- // Метод для настройки рамки, где должно помещаться лицо
26
- getContourCoordinate(width: number, height: number) {
27
- return {
28
- x: width * 0.25,
29
- y: height * 0.05,
30
- width: width * 0.5,
31
- height: height * 0.9,
32
- }
33
- }
34
-
35
- getBoxData(box: any) {
36
- if (!box) return null
37
- return {
38
- x: box.x,
39
- y: box.y,
40
- width: box.width,
41
- height: box.height,
42
- }
43
- }
44
-
45
- setStylesForCanvas(canvasContainer: any) {
46
- canvasContainer.width = '100%'
47
- canvasContainer.height = '100%'
48
- canvasContainer.style.position = 'absolute'
49
- canvasContainer.style.top = '0'
50
- canvasContainer.style.left = '0'
51
- }
52
-
53
- // Метод для рассчёта того, что лицо полностью помещается в рамке
54
- checkFaceInclusion(frame: any, face: any) {
55
- if (!frame || !face) return false
56
-
57
- if (face.width > frame.width || face.height > frame.height) {
58
- return false
59
- }
60
-
61
- const faceXmin = face.x
62
- const faceXmax = face.x + face.width
63
- const faceYmin = face.y
64
- const faceYmax = face.y + face.height
65
-
66
- const frameXmin = frame.x
67
- const frameXmax = frame.x + frame.width
68
- const frameYmin = frame.y
69
- const frameYmax = frame.y + frame.height
70
-
71
- return faceXmin >= frameXmin && faceXmax <= frameXmax && faceYmin >= frameYmin && faceYmax <= frameYmax
72
- }
73
-
74
- async getFaceDetections(videoRef: any) {
75
- if (!videoRef) return []
76
- return faceapi
77
- .detectAllFaces(videoRef, new faceapi.TinyFaceDetectorOptions())
78
- .withFaceLandmarks()
79
- .withFaceExpressions()
80
- }
81
-
82
- getCanvas(videoRef: any) {
83
- return faceapi.createCanvasFromMedia(videoRef)
84
- }
85
-
86
- getResizedAndDetection(canvas: any, detections: any, ctx: any, videoWidth: number, videoHeight: number) {
87
- faceapi.matchDimensions(canvas, { width: videoWidth, height: videoHeight })
88
-
89
- const resized = faceapi.resizeResults(detections, {
90
- width: videoWidth,
91
- height: videoHeight,
92
- })
93
-
94
- ctx.clearRect(0, 0, videoWidth, videoHeight)
95
-
96
- faceapi.draw.drawDetections(canvas, resized)
97
- faceapi.draw.drawFaceLandmarks(canvas, resized)
98
- faceapi.draw.drawFaceExpressions(canvas, resized)
99
- }
100
-
101
- async getFaceSnapshot(inputImage: any, box: any) {
102
- const regionsToExtract = [new faceapi.Rect(box.x, box.y, box.width, box.height)]
103
- const faceImages = await faceapi.extractFaces(inputImage, regionsToExtract)
104
-
105
- if (faceImages.length) {
106
- const dataUrl = faceImages[0].toDataURL('image/jpeg')
107
- return dataUrl.replace(/^data:image\/\w+;base64,/, '')
108
- }
109
-
110
- return null
111
- }
112
-
113
- async initModels() {
114
- let date = new Date()
115
- console.log(date)
116
- try {
117
- await Promise.all([
118
- faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
119
- faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
120
- faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
121
- faceapi.nets.faceExpressionNet.loadFromUri('/models'),
122
- //faceapi.nets.ssdMobilenetv1.loadFromUri('/models'),
123
- ])
124
- } catch (error) {
125
- console.error(error)
126
- }
127
- date = new Date()
128
- console.log(date)
129
- }
130
- }
131
-
132
- let api: PhotoService
133
-
134
- export default function usePhotoService() {
135
- if (!api) api = new PhotoService()
136
- return api
137
- }
1
+ import * as faceapi from 'face-api.js'
2
+
3
+ class PhotoService {
4
+ // async getFaceSnapshot(inputImage: any, box: any) {
5
+ // const regionsToExtract = [new faceapi.Rect(box.x, box.y, box.width, box.height)]
6
+ // const faceImages = await faceapi.extractFaces(inputImage, regionsToExtract)
7
+ // if (faceImages.length) {
8
+ // const dataUrl = faceImages[0].toDataURL('image/jpeg')
9
+ // photo.value = dataUrl.replace(/^data:image\/\w+;base64,/, '')
10
+ // }
11
+ // }
12
+
13
+ // Метод настройки конфига для стрима
14
+ getVideoStreamConfig(width: number, height: number) {
15
+ return {
16
+ audio: false,
17
+ video: {
18
+ width: { min: width, ideal: width },
19
+ height: { min: height, ideal: height },
20
+ facingMode: 'environment', // или 'user' для фронтальной камеры
21
+ },
22
+ }
23
+ }
24
+
25
+ // Метод для настройки рамки, где должно помещаться лицо
26
+ getContourCoordinate(width: number, height: number) {
27
+ return {
28
+ x: width * 0.25,
29
+ y: height * 0.05,
30
+ width: width * 0.5,
31
+ height: height * 0.9,
32
+ }
33
+ }
34
+
35
+ getBoxData(box: any) {
36
+ if (!box) return null
37
+ return {
38
+ x: box.x,
39
+ y: box.y,
40
+ width: box.width,
41
+ height: box.height,
42
+ }
43
+ }
44
+
45
+ setStylesForCanvas(canvasContainer: any) {
46
+ canvasContainer.width = '100%'
47
+ canvasContainer.height = '100%'
48
+ canvasContainer.style.position = 'absolute'
49
+ canvasContainer.style.top = '0'
50
+ canvasContainer.style.left = '0'
51
+ }
52
+
53
+ // Метод для рассчёта того, что лицо полностью помещается в рамке
54
+ checkFaceInclusion(frame: any, face: any) {
55
+ if (!frame || !face) return false
56
+
57
+ if (face.width > frame.width || face.height > frame.height) {
58
+ return false
59
+ }
60
+
61
+ const faceXmin = face.x
62
+ const faceXmax = face.x + face.width
63
+ const faceYmin = face.y
64
+ const faceYmax = face.y + face.height
65
+
66
+ const frameXmin = frame.x
67
+ const frameXmax = frame.x + frame.width
68
+ const frameYmin = frame.y
69
+ const frameYmax = frame.y + frame.height
70
+
71
+ return faceXmin >= frameXmin && faceXmax <= frameXmax && faceYmin >= frameYmin && faceYmax <= frameYmax
72
+ }
73
+
74
+ async getFaceDetections(videoRef: any) {
75
+ if (!videoRef) return []
76
+ return faceapi
77
+ .detectAllFaces(videoRef, new faceapi.TinyFaceDetectorOptions())
78
+ .withFaceLandmarks()
79
+ .withFaceExpressions()
80
+ }
81
+
82
+ getCanvas(videoRef: any) {
83
+ return faceapi.createCanvasFromMedia(videoRef)
84
+ }
85
+
86
+ getResizedAndDetection(canvas: any, detections: any, ctx: any, videoWidth: number, videoHeight: number) {
87
+ faceapi.matchDimensions(canvas, { width: videoWidth, height: videoHeight })
88
+
89
+ const resized = faceapi.resizeResults(detections, {
90
+ width: videoWidth,
91
+ height: videoHeight,
92
+ })
93
+
94
+ ctx.clearRect(0, 0, videoWidth, videoHeight)
95
+
96
+ faceapi.draw.drawDetections(canvas, resized)
97
+ faceapi.draw.drawFaceLandmarks(canvas, resized)
98
+ faceapi.draw.drawFaceExpressions(canvas, resized)
99
+ }
100
+
101
+ async getFaceSnapshot(inputImage: any, box: any) {
102
+ const regionsToExtract = [new faceapi.Rect(box.x, box.y, box.width, box.height)]
103
+ const faceImages = await faceapi.extractFaces(inputImage, regionsToExtract)
104
+
105
+ if (faceImages.length) {
106
+ const dataUrl = faceImages[0].toDataURL('image/jpeg')
107
+ return dataUrl.replace(/^data:image\/\w+;base64,/, '')
108
+ }
109
+
110
+ return null
111
+ }
112
+
113
+ async initModels() {
114
+ let date = new Date()
115
+ console.log(date)
116
+ try {
117
+ await Promise.all([
118
+ faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
119
+ faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
120
+ faceapi.nets.faceRecognitionNet.loadFromUri('/models'),
121
+ faceapi.nets.faceExpressionNet.loadFromUri('/models'),
122
+ //faceapi.nets.ssdMobilenetv1.loadFromUri('/models'),
123
+ ])
124
+ } catch (error) {
125
+ console.error(error)
126
+ }
127
+ date = new Date()
128
+ console.log(date)
129
+ }
130
+ }
131
+
132
+ let api: PhotoService
133
+
134
+ export default function usePhotoService() {
135
+ if (!api) api = new PhotoService()
136
+ return api
137
+ }