- Не хватает подходящих экспертов. Вернитесь назад и выберите больше экспертов для
- указанных кейсов или пригласите новых.
+ Не хватает экспертов. Измените состав у проектов или вернитесь к выбору экспертов для
+ кейсов.
- } @else if (preview.assignments.length) {
- Распределение готово. Проверьте список ниже и подтвердите.
}
-
- @for (assignment of preview.assignments; track $index) {
-
- {{ assignment.projectName }}{{ caseLabel(assignment.caseName ?? null) }}{{ assignment.expertName }}
-
- }
- @for (shortage of preview.shortages; track shortage.projectId) {
-
- {{ shortage.projectName }} · {{ caseLabel(shortage.caseName ?? null) }} — нужно еще
- {{ shortage.missing }}
- {{ shortage.missing | pluralize: ["эксперт", "эксперта", "экспертов"] }}
-
- }
- @if (!preview.assignments.length && !preview.shortages.length) {
-
- Для всех доступных к оценке проектов уже выбран нужный состав экспертов.
-
+
-
Нагрузка по всем кейсам
-
Проекты, которые еще нужно оценить
-
+
+ @if (allocationHint()) {
+
{{ allocationHint() }}
+ }
+
} @else {
-
Шаг 1 из 2. Выберите экспертов для кейсов
-
- Система добавит экспертов проектам, где их не хватает: по
- {{ snapshot()?.requiredEvaluators }} на проект. Сначала вы проверите результат, затем
- подтвердите назначения.
-
+
Шаг 1 из 2 · Эксперты для кейсов
+
По {{ snapshot()?.requiredEvaluators }}
+ {{
+ snapshot()?.requiredEvaluators ?? 1 | pluralize: ["эксперту", "эксперта", "экспертов"]
+ }}
+ на проект
-
Эксперты могут участвовать в нескольких кейсах. Нагрузка учитывается суммарно.
}
- @if ((plan()?.unavailableProjects ?? snapshot()?.unavailableProjects)?.length) {
-
- Некоторые проекты пока недоступны экспертам
- @for (
- project of plan()?.unavailableProjects ?? snapshot()?.unavailableProjects;
- track project.projectId
- ) {
- {{ project.projectName }} — черновик. Автору нужно опубликовать проект.
- }
-
+ }
+ @case ("allocation-project") {
+
{{ allocationProject()?.name }}
+ @if (allocationProject()?.experts?.length) {
+
Уже назначенные эксперты останутся в составе.
}
+
+
Выбрано {{ chosenExperts().size }} из {{ snapshot()?.requiredEvaluators }}
+
}
@case ("project") {
{{ targetNames() }}
diff --git a/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.scss b/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.scss
index f06497599..3a1bf9a3b 100644
--- a/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.scss
+++ b/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.scss
@@ -918,6 +918,200 @@
opacity: 1;
}
+.experts__floating--projects {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto 32px;
+ background: var(--light-white);
+ border: 1px solid var(--medium-grey-for-outline);
+
+ > span {
+ grid-column: 1 / -1;
+ }
+
+ .ui-button--primary {
+ min-width: 0;
+ }
+
+ .ui-button:disabled {
+ color: var(--grey-for-text);
+ background: var(--medium-grey-for-outline);
+ border-color: var(--medium-grey-for-outline);
+ opacity: 1;
+ }
+}
+
+.experts__project-summary {
+ display: grid;
+ gap: 4px;
+ min-width: 0;
+ overflow-wrap: anywhere;
+
+ span {
+ color: var(--grey-for-text);
+ }
+}
+
+.experts__floating--projects .experts__project-clear {
+ align-self: center;
+ width: 32px;
+ min-width: 32px;
+ min-height: 32px;
+ color: var(--grey-for-text);
+ background: var(--light-gray);
+ border-color: var(--light-gray);
+}
+
+.experts__attention {
+ display: flex;
+ gap: 12px;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ padding: 12px 16px;
+ font: inherit;
+ color: var(--black);
+ text-align: left;
+ cursor: pointer;
+ background: color-mix(in srgb, var(--gold) 28%, var(--light-white));
+ border: 1px solid transparent;
+ border-radius: 8px;
+
+ > span:first-child {
+ display: grid;
+ gap: 4px;
+ }
+
+ > span:last-child {
+ flex-shrink: 0;
+ color: var(--accent-dark);
+ }
+
+ &:hover,
+ &--active {
+ border-color: var(--gold);
+ }
+
+ &:focus-visible {
+ outline: 2px solid var(--accent-dark);
+ outline-offset: 3px;
+ }
+}
+
+.experts__allocation-project {
+ display: grid;
+ gap: 12px;
+ padding: 16px 0;
+ border-bottom: 1px solid var(--medium-grey-for-outline);
+}
+
+.experts__allocation-heading {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto auto;
+ gap: 12px;
+ align-items: center;
+
+ h3 {
+ font-size: 14px;
+ overflow-wrap: anywhere;
+ }
+
+ > span {
+ white-space: nowrap;
+ }
+}
+
+.experts__allocation-members {
+ display: grid;
+ gap: 8px;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+
+ li {
+ display: flex;
+ gap: 12px;
+ justify-content: space-between;
+ }
+
+ li > span:first-child {
+ min-width: 0;
+ overflow-wrap: anywhere;
+ }
+
+ li > span:last-child {
+ flex-shrink: 0;
+ color: var(--grey-for-text);
+ }
+
+ li > .experts__allocation-new:last-child {
+ color: var(--accent-dark);
+ }
+}
+
+.experts__dialog p.experts__allocation-shortage {
+ font-weight: 600;
+ color: var(--black);
+}
+
+.experts__allocation-case {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto;
+ gap: 12px;
+ align-items: center;
+
+ > p {
+ grid-column: 1 / -1;
+ }
+}
+
+.experts__allocation-load summary {
+ padding-block: 8px;
+ cursor: pointer;
+}
+
+.experts__allocation-actions {
+ justify-content: space-between;
+}
+
+@media (max-width: 999px) {
+ .experts:not(.experts--people) {
+ padding-bottom: 144px;
+ }
+
+ .experts__floating--projects {
+ grid-template-columns: minmax(0, 1fr) 32px;
+
+ > .ui-button--primary {
+ grid-row: 2;
+ grid-column: 1 / -1;
+ }
+
+ > .experts__project-clear {
+ grid-row: 1;
+ grid-column: 2;
+ }
+ }
+}
+
+@media (max-width: 599px) {
+ .experts__allocation-heading {
+ grid-template-columns: minmax(0, 1fr) auto;
+
+ button {
+ grid-column: 1 / -1;
+ }
+ }
+
+ .experts__allocation-case {
+ grid-template-columns: minmax(0, 1fr);
+ }
+
+ .experts__allocation-actions {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr);
+ }
+}
+
@media (max-width: 999px) {
.experts__mobile-tools {
display: block;
diff --git a/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.spec.ts b/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.spec.ts
index 1caa9013c..ddddc6230 100644
--- a/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.spec.ts
+++ b/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.spec.ts
@@ -96,11 +96,13 @@ describe("Управление экспертами", () => {
const { fixture, component, api } = setup();
component.open("auto");
fixture.detectChanges();
- expect(component.canPreviewAllocation()).toBe(false);
+ expect(component.canPreviewAllocation()).toBe(true);
component.openPool("Сбер");
+ component.chosenExperts.set(new Set());
component.toggleCandidate(snapshot.experts[0]);
component.savePool();
component.openPool("Т-Банк");
+ component.chosenExperts.set(new Set());
component.toggleCandidate(snapshot.experts[0]);
component.savePool();
api.allocation.mockReturnValue(
@@ -108,6 +110,7 @@ describe("Управление экспертами", () => {
);
component.previewAllocation();
expect(api.allocation).toHaveBeenCalledWith(42, {
+ seed: 0,
expertIds: [1],
revision: "v1",
casePools: [
@@ -139,6 +142,115 @@ describe("Управление экспертами", () => {
caseNames: ["Сбер"],
});
});
+ it("показывает внимание только при нехватке и включает фильтр по всем проблемным проектам", () => {
+ const { component } = setup();
+ expect(component.attentionProjects().length).toBe(3);
+ component.showAttentionProjects();
+ expect(component.distributionStatus.value).toBe("missing");
+ expect(component.attentionActive()).toBe(true);
+ component.showAttentionProjects();
+ expect(component.distributionStatus.value).toBe("all");
+ component.snapshot.update(s => ({
+ ...s!,
+ projects: s!.projects!.map(p => ({
+ ...p,
+ experts: [projects[0].experts[0], { ...projects[0].experts[0], expertId: 8 }],
+ })),
+ }));
+ expect(component.attentionProjects()).toEqual([]);
+ expect(component.pendingAutoGroups()).toEqual([]);
+ });
+ it("в предпросмотре показывает существующих экспертов вместе с добавляемыми", async () => {
+ const { component, fixture } = setup();
+ component.plan.set({
+ revision: "v1",
+ planToken: "signed",
+ assignments: [
+ { projectId: 10, projectName: "Тест", expertId: 3, expertName: "Новый эксперт" },
+ ],
+ shortages: [],
+ load: [],
+ });
+ component.modal.set("auto");
+ fixture.detectChanges();
+ await new Promise(resolve => setTimeout(resolve, 0));
+ fixture.detectChanges();
+ const card = document.querySelector(".experts__allocation-project")!;
+ expect(card.textContent).toContain("2 из 2");
+ expect(card.textContent).toContain("Уже назначен");
+ expect(card.textContent).toContain("Новый эксперт");
+ expect(card.textContent).toContain("Добавится");
+ });
+ it("другой вариант меняет seed и не применяет план", () => {
+ const { component, api } = setup();
+ component.open("auto");
+ const plan = { revision: "v1", planToken: "signed", assignments: [], shortages: [], load: [] };
+ component.plan.set(plan);
+ component.allocationOverrides.set(new Map([[10, [3]]]));
+ api.allocation.mockReturnValue(of(plan));
+ component.rerollAllocation();
+ expect(api.allocation.mock.calls[0][1].seed).toBe(1);
+ expect(api.allocation.mock.calls[0][1].assignmentOverrides).toBeUndefined();
+ expect(component.allocationOverrides().size).toBe(0);
+ expect(component.allocationHint()).toContain("тот же вариант");
+ expect(api.applyAllocation).not.toHaveBeenCalled();
+ });
+ it("редактор меняет только новые назначения и получает новый подписанный предпросмотр", () => {
+ const { component, api } = setup();
+ const extra = [3, 4].map(id => ({
+ ...snapshot.experts[0],
+ id,
+ userId: 100 + id,
+ name: `Эксперт ${id}`,
+ }));
+ component.snapshot.update(s => ({ ...s!, experts: [...s!.experts, ...extra] }));
+ component.open("auto");
+ const plan = {
+ revision: "v1",
+ planToken: "old",
+ assignments: [{ projectId: 10, projectName: "Тест", expertId: 3, expertName: "Эксперт 3" }],
+ shortages: [],
+ load: [],
+ };
+ component.plan.set(plan);
+ component.editAllocationProject(10);
+ expect(component.candidateReason(snapshot.experts[0])).toContain("Уже назначен");
+ component.toggleCandidate(extra[0]);
+ component.toggleCandidate(extra[1]);
+ api.allocation.mockReturnValue(
+ of({ ...plan, planToken: "new", assignments: [{ ...plan.assignments[0], expertId: 4 }] }),
+ );
+ component.saveAllocationProject();
+ expect(api.allocation.mock.calls[0][1].assignmentOverrides).toEqual([
+ { projectId: 10, expertIds: [4] },
+ ]);
+ expect(component.plan()?.planToken).toBe("new");
+ expect(component.modal()).toBe("auto");
+ expect(api.applyAllocation).not.toHaveBeenCalled();
+ });
+ it("ошибка пересчета сохраняет старый план и выбор в редакторе", () => {
+ const { component, api } = setup();
+ component.snapshot.update(s => ({
+ ...s!,
+ experts: [...s!.experts, { ...snapshot.experts[0], id: 3, userId: 103 }],
+ }));
+ component.open("auto");
+ const plan = {
+ revision: "v1",
+ planToken: "old",
+ assignments: [{ projectId: 10, projectName: "Тест", expertId: 3, expertName: "Эксперт 3" }],
+ shortages: [],
+ load: [],
+ };
+ component.plan.set(plan);
+ component.editAllocationProject(10);
+ api.allocation.mockReturnValue(throwError(() => new HttpErrorResponse({ status: 409 })));
+ component.saveAllocationProject();
+ expect(component.plan()?.planToken).toBe("old");
+ expect(component.modal()).toBe("allocation-project");
+ expect(component.chosenExperts().has(3)).toBe(true);
+ expect(component.allocationOverrides().size).toBe(0);
+ });
const snapshot: ExpertWorkspace = {
revision: "v1",
requiredEvaluators: 2,
@@ -266,7 +378,7 @@ describe("Управление экспертами", () => {
it("pending исключён из распределения, план с нехваткой нельзя применить", () => {
const { component, api } = setup();
component.open("auto");
- expect(component.poolExperts("Сбер")).toEqual([]);
+ expect(component.poolExperts("Сбер").map(e => e.id)).toEqual([1]);
component.plan.set({
revision: "v1",
planToken: "signed",
@@ -354,13 +466,15 @@ describe("Управление экспертами", () => {
const restricted = { ...snapshot.experts[0], id: 3, allCases: false, caseNames: ["Сбер"] };
component.snapshot.update(s => ({ ...s!, experts: [...s!.experts, restricted] }));
component.open("auto");
- expect(component.poolExperts("Сбер")).toEqual([]);
+ expect(component.poolExperts("Сбер").map(e => e.id)).toEqual([1, 3]);
component.openPool("Сбер");
+ component.chosenExperts.set(new Set());
component.toggleCandidate(snapshot.experts[0]);
component.toggleCandidate(restricted);
component.savePool();
expect(component.poolExperts("Сбер").map(e => e.id)).toEqual([1, 3]);
component.openPool("Т-Банк");
+ component.chosenExperts.set(new Set());
component.toggleCandidate(snapshot.experts[0]);
component.toggleCandidate(restricted);
expect(component.chosenExperts().has(3)).toBe(false);
@@ -371,9 +485,11 @@ describe("Управление экспертами", () => {
const { component, api } = setup();
component.open("auto");
component.openPool("Сбер");
+ component.chosenExperts.set(new Set());
component.toggleCandidate(snapshot.experts[0]);
component.savePool();
component.openPool("Т-Банк");
+ component.chosenExperts.set(new Set());
component.toggleCandidate(snapshot.experts[0]);
component.savePool();
api.allocation.mockReturnValue(
@@ -381,6 +497,7 @@ describe("Управление экспертами", () => {
);
component.previewAllocation();
expect(api.allocation).toHaveBeenCalledWith(42, {
+ seed: 0,
expertIds: [1],
revision: "v1",
casePools: [
@@ -518,6 +635,7 @@ describe("Управление экспертами", () => {
}));
component.open("auto");
component.openPool("Сбер");
+ component.chosenExperts.set(new Set());
expect(component.chosenExperts().size).toBe(0);
expect(component.candidateReason(extra)).toBeNull();
component.toggleCandidate(snapshot.experts[0]);
diff --git a/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.ts b/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.ts
index 247fd9c47..3c4595d0d 100644
--- a/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.ts
+++ b/projects/social_platform/src/app/ui/pages/program/management/experts/experts.component.ts
@@ -118,9 +118,39 @@ export class ManagementExpertsComponent {
readonly bulkScope = signal(false);
readonly bulkRevoke = signal(false);
readonly modal = signal<
- "invite" | "auto" | "quota" | "revoke" | "method" | "project" | "scope" | "pool" | null
+ | "invite"
+ | "auto"
+ | "quota"
+ | "revoke"
+ | "method"
+ | "project"
+ | "scope"
+ | "pool"
+ | "allocation-project"
+ | null
>(null);
readonly plan = signal
(null);
+ readonly allocationSeed = signal(0);
+ readonly allocationOverrides = signal(new Map());
+ readonly allocationHint = signal(null);
+ readonly allocationProjectId = signal(null);
+ readonly allocationProject = computed(() =>
+ this.allProjects().find(p => p.id === this.allocationProjectId()),
+ );
+ readonly allocationProjects = computed(() => {
+ const plan = this.plan();
+ return this.allProjects()
+ .filter(
+ p =>
+ plan?.assignments.some(a => a.projectId === p.id) ||
+ plan?.shortages.some(s => s.projectId === p.id),
+ )
+ .map(project => ({
+ ...project,
+ additions: plan!.assignments.filter(a => a.projectId === project.id),
+ missing: plan!.shortages.find(s => s.projectId === project.id)?.missing ?? 0,
+ }));
+ });
readonly quotaPreview = signal(null);
readonly chosenExperts = signal(new Set());
readonly search = this.fb.control("");
@@ -204,6 +234,10 @@ export class ManagementExpertsComponent {
(this.projectPage() + 1) * this.pageSize,
),
);
+ readonly attentionProjects = computed(() =>
+ this.allProjects().filter(p => p.experts.length < (this.snapshot()?.requiredEvaluators ?? 1)),
+ );
+ readonly attentionActive = computed(() => this.distributionStatusValue() === "missing");
readonly selection = computed(() =>
this.allProjects().filter(p => this.selectedProjects().has(p.id)),
);
@@ -247,6 +281,7 @@ export class ManagementExpertsComponent {
.filter(g => g.missing)
.every(g => this.poolExperts(g.name).length),
);
+ readonly pendingAutoGroups = computed(() => this.autoGroups().filter(g => g.missing));
readonly candidateExperts = computed(() =>
(this.snapshot()?.experts ?? []).filter(
e =>
@@ -308,6 +343,8 @@ export class ManagementExpertsComponent {
return this.bulkScope() ? "Кейсы выбранных экспертов" : "Кейсы эксперта";
case "pool":
return "Эксперты для кейса «" + this.caseLabel(this.poolCase()) + "»";
+ case "allocation-project":
+ return "Эксперты проекта";
case "project":
return this.targets().length > 1
? "Назначить экспертов нескольким проектам"
@@ -697,16 +734,26 @@ export class ManagementExpertsComponent {
}
if (kind === "quota") this.quota.setValue(this.snapshot()?.requiredEvaluators ?? 1);
if (kind === "auto") {
+ this.allocationOverrides.set(new Map());
+ this.allocationSeed.set(0);
+ this.allocationHint.set(null);
this.casePools.set(
this.autoGroups().map(g => ({
caseName: g.name,
- expertIds: [],
+ expertIds: this.joined()
+ .filter(e => this.eligibleFor(e, g.name))
+ .map(e => Number(e.id)),
})),
);
}
}
async close(): Promise {
if (this.busy()) return;
+ if (this.modal() === "allocation-project") {
+ this.modal.set("auto");
+ this.dialogError.set(null);
+ return;
+ }
if (this.dirty() && !(await this.confirmDiscard()())) return;
this.modal.set(null);
this.dialogError.set(null);
@@ -761,7 +808,23 @@ export class ManagementExpertsComponent {
}
previewAllocation(): void {
if (!this.canPreviewAllocation()) return;
+ this.calculateAllocation(this.allocationOverrides(), this.allocationSeed());
+ }
+ rerollAllocation(): void {
+ if (this.busy() || !this.canPreviewAllocation()) return;
+ this.calculateAllocation(new Map(), (this.allocationSeed() + 1) % 2147483648, true);
+ }
+ private calculateAllocation(
+ overrides: Map,
+ seed: number,
+ reroll = false,
+ ): void {
const pools = this.casePools();
+ const before = JSON.stringify(
+ this.plan()
+ ?.assignments.map(a => `${a.projectId}:${a.expertId}`)
+ .sort(),
+ );
this.request(
this.api.allocation(
this.programId(),
@@ -770,12 +833,64 @@ export class ManagementExpertsComponent {
expertIds: [...new Set(pools.flatMap(p => p.expertIds))],
casePools: pools,
revision: this.snapshot()!.revision,
+ seed,
+ ...(overrides.size
+ ? {
+ assignmentOverrides: [...overrides].map(([projectId, expertIds]) => ({
+ projectId,
+ expertIds,
+ })),
+ }
+ : {}),
}
: { expertIds: [...this.chosenExperts()] },
),
- plan => this.plan.set(plan),
+ plan => {
+ this.allocationOverrides.set(overrides);
+ this.allocationSeed.set(seed);
+ this.allocationHint.set(
+ reroll &&
+ before ===
+ JSON.stringify(plan.assignments.map(a => `${a.projectId}:${a.expertId}`).sort())
+ ? "Получился тот же вариант. Можно изменить состав у проекта или выбрать других экспертов для кейса."
+ : null,
+ );
+ this.plan.set(plan);
+ this.modal.set("auto");
+ },
);
}
+ editAllocationProject(id: number): void {
+ if (this.busy()) return;
+ const project = this.allProjects().find(p => p.id === id);
+ if (!project || !this.plan()) return;
+ this.allocationProjectId.set(id);
+ this.chosenExperts.set(
+ new Set([
+ ...project.experts.map(e => e.expertId),
+ ...this.plan()!
+ .assignments.filter(a => a.projectId === id)
+ .map(a => a.expertId),
+ ]),
+ );
+ this.expertSearch.reset("");
+ this.dialogError.set(null);
+ this.modal.set("allocation-project");
+ }
+ saveAllocationProject(): void {
+ const project = this.allocationProject();
+ if (!project || this.busy()) return;
+ const limit = this.snapshot()?.requiredEvaluators ?? 1;
+ if (this.chosenExperts().size !== limit) return;
+ const overrides = new Map(
+ this.allocationProjects().map(p => [p.id, p.additions.map(e => e.expertId)]),
+ );
+ overrides.set(
+ project.id,
+ [...this.chosenExperts()].filter(id => !project.experts.some(e => e.expertId === id)),
+ );
+ this.calculateAllocation(overrides, this.allocationSeed());
+ }
applyAllocation(): void {
const plan = this.plan();
if (!plan || plan.shortages.length) return;
@@ -818,6 +933,12 @@ export class ManagementExpertsComponent {
distributionCaseKey(name: string | null): string {
return JSON.stringify(name);
}
+ showAttentionProjects(): void {
+ const active = this.attentionActive();
+ this.distributionSearch.reset("");
+ this.distributionCase.setValue("all");
+ this.distributionStatus.setValue(active ? "all" : "missing");
+ }
scopeLabel(expert: ExpertRow): string {
return (expert.allCases ?? true)
? "Все кейсы"
@@ -881,6 +1002,23 @@ export class ManagementExpertsComponent {
candidateReason(expert: ExpertRow): string | null {
if (expert.status !== "joined") return "Приглашение еще не принято";
const id = Number(expert.id);
+ if (this.modal() === "allocation-project") {
+ const project = this.allocationProject();
+ if (!project) return "Проект не найден";
+ if (project.experts.some(e => e.expertId === id)) return "Уже назначен — останется в составе";
+ if (!this.poolExperts(project.caseName).some(e => Number(e.id) === id))
+ return "Не выбран для этого кейса";
+ if (
+ expert.userId &&
+ (project.leaderId === expert.userId || project.teamUserIds.includes(expert.userId))
+ )
+ return "Проект собственной команды";
+ if (
+ !this.chosenExperts().has(id) &&
+ this.chosenExperts().size >= (this.snapshot()?.requiredEvaluators ?? 1)
+ )
+ return "Сначала снимите другого эксперта";
+ }
if (this.modal() === "project") {
const targets = this.targets();
if (targets.length === 1 && targets[0].experts.some(e => e.expertId === id && e.protected))
@@ -997,6 +1135,8 @@ export class ManagementExpertsComponent {
),
);
this.plan.set(null);
+ this.allocationOverrides.set(new Map());
+ this.allocationHint.set(null);
this.modal.set("auto");
}
}