{"version":3,"sources":["node_modules/@vendasta/email-builder/fesm2020/vendasta-email-builder.mjs","libs/email-ui/email-builder/src/components/dynamic-component-selector/dynamic-component-selector.service.ts","libs/email-ui/email-builder/src/components/dynamic-component-selector/dynamic-component-dialog/dynamic-component-dialog.component.ts","libs/email-ui/email-builder/src/components/dynamic-component-selector/dynamic-component-dialog/dynamic-component-dialog.component.html","libs/email-ui/email-builder/src/components/rich-text-editor/rich-text-editor.component.ts","libs/email-ui/email-builder/src/components/rich-text-editor/rich-text-editor.component.html","libs/email-ui/email-builder/src/components/dynamic-component-selector/dynamic-component-selector.component.ts","libs/email-ui/email-builder/src/components/dynamic-component-selector/dynamic-component-selector.component.html","libs/email-ui/email-builder/src/components/dynamic-component-selector/dynamic-component-selector.module.ts","libs/email-ui/email-builder/src/components/dynamic-component-selector/index.ts","libs/email-ui/email-builder/src/shared.ts","libs/email-ui/email-builder/src/components/preview-context-selector/contact-selector-modal/contact-selector.component.ts","libs/email-ui/email-builder/src/components/preview-context-selector/contact-selector-modal/contact-selector.component.html","libs/email-ui/email-builder/src/components/preview-context-selector/preview-context-selector.component.ts","libs/email-ui/email-builder/src/components/preview-context-selector/preview-context-selector.component.html","libs/email-ui/email-builder/src/components/preview-context-selector/preview-context-selector.module.ts","libs/email-ui/email-builder/src/dependencies/tokens.ts","libs/email-ui/email-builder/src/components/unsaved-changes-dialog/unsaved-changes-dialog.component.ts","libs/email-ui/email-builder/src/components/unsaved-changes-dialog/unsaved-changes-dialog.component.html","libs/email-ui/email-builder/src/services/has-unsaved-changes.guard.ts","libs/email-ui/email-builder/src/services/preview-rendering.service.ts","libs/email-ui/email-builder/src/services/email-preview-refresh.service.ts","libs/email-ui/email-builder/src/components/email-advanced-settings/empty-settings.ts","libs/email-ui/email-builder/src/directives/hold-shift-to-change-number-field-by-ten.directive.ts","libs/email-ui/email-builder/src/components/email-advanced-settings/email-advanced-settings.component.ts","libs/email-ui/email-builder/src/components/email-advanced-settings/email-advanced-settings.component.html","libs/email-ui/email-builder/src/inbox-preview.ts","libs/content-generation/src/lib/assets/i18n/en_devel.json","libs/content-generation/src/lib/assets/i18n/content-generation-i18n.module.ts","libs/content-generation/src/lib/image-generation/image-generation.service.ts","libs/content-generation/src/lib/image-generation/image-generation-dialog/image-generation-dialog.component.ts","libs/content-generation/src/lib/image-generation/image-generation-dialog/image-generation-dialog.component.html","libs/content-generation/src/index.ts","libs/email-ui/email-builder/src/services/image-upload.service.ts","libs/galaxy/resize/src/resize/resize.component.ts","libs/galaxy/resize/src/resize/resize.component.html","libs/email-ui/email-editor-preview/src/email-editor-preview.component.ts","libs/email-ui/email-editor-preview/src/email-editor-preview.component.html","libs/email-ui/email-builder/src/blocks/rich-text-block/after-block-drag.service.ts","libs/email-ui/email-builder/src/types/contentblocks.ts","libs/email-ui/email-builder/src/blocks/button-block/button-block.component.ts","libs/email-ui/email-builder/src/blocks/button-block/button-block.component.html","libs/email-ui/email-builder/src/blocks/contact-card/contact-card.component.ts","libs/email-ui/email-builder/src/blocks/contact-card/contact-card.component.html","libs/email-ui/email-builder/src/blocks/divider-block/divider-block.component.ts","libs/email-ui/email-builder/src/blocks/divider-block/divider-block.component.html","libs/email-ui/email-builder/src/blocks/heading-block/heading-block.component.ts","libs/email-ui/email-builder/src/blocks/heading-block/heading-block.component.html","libs/email-ui/email-builder/src/blocks/html-block/html-block.component.ts","libs/email-ui/email-builder/src/blocks/html-block/html-block.component.html","libs/email-ui/email-builder/src/blocks/image-and-text-block/image-and-text-block.component.ts","libs/email-ui/email-builder/src/blocks/image-and-text-block/image-and-text-block.component.html","libs/email-ui/email-builder/src/blocks/image-block/image-block.component.ts","libs/email-ui/email-builder/src/blocks/image-block/image-block.component.html","libs/email-ui/email-builder/src/blocks/review-request-links-block/review-request-links-block.component.ts","libs/email-ui/email-builder/src/blocks/review-request-links-block/review-request-links-block.component.html","libs/email-ui/email-builder/src/components/suggest-content-dialog/suggest-content-dialog.component.ts","libs/email-ui/email-builder/src/components/suggest-content-dialog/suggest-content-dialog.component.html","libs/email-ui/email-builder/src/blocks/rich-text-block/rich-text-block.component.ts","libs/email-ui/email-builder/src/blocks/rich-text-block/rich-text-block.component.html","libs/email-ui/email-builder/src/blocks/simple-table-block/simple-table-block.component.ts","libs/email-ui/email-builder/src/blocks/simple-table-block/simple-table-block.component.html","libs/email-ui/email-builder/src/blocks/spacer-block/spacer-block.component.ts","libs/email-ui/email-builder/src/blocks/spacer-block/spacer-block.component.html","libs/email-ui/email-builder/src/services/feature-flag.service.ts","libs/email-ui/email-builder/src/blocks/nps-block/nps-block.component.ts","libs/email-ui/email-builder/src/blocks/nps-block/nps-block.component.html","libs/email-ui/email-builder/src/components/email-block-padding/email-block-padding.component.ts","libs/email-ui/email-builder/src/components/email-block-padding/email-block-padding.component.html","libs/email-ui/email-builder/src/components/email-blocks-list/email-blocks-list.component.ts","libs/email-ui/email-builder/src/components/email-blocks-list/email-blocks-list.component.html","libs/email-ui/email-builder/src/email-builder.component.ts","libs/email-ui/email-builder/src/email-builder.component.html","libs/galaxy/resize/src/resize.module.ts","libs/galaxy/resize/src/resize/interface.ts","libs/galaxy/resize/public_api.ts","libs/galaxy/resize/index.ts","libs/email-ui/email-editor-preview/src/email-editor-preview.module.ts","libs/email-ui/email-editor-preview/public_api.ts","libs/email-ui/email-editor-preview/index.ts","libs/email-ui/email-builder/src/email-builder.module.ts","libs/email-ui/email-builder/src/services/email-builder-data.service.ts","libs/email-ui/email-builder/public_api.ts","libs/email-ui/email-builder/index.ts"],"sourcesContent":["import * as i0 from '@angular/core';\nimport { Injectable } from '@angular/core';\nimport * as i1 from '@angular/common/http';\nimport { HttpHeaders } from '@angular/common/http';\nimport { map } from 'rxjs/operators';\n\n// *********************************\n// Code generated by sdkgen\n// DO NOT EDIT!.\n//\n// Enums.\n// *********************************\nvar OwnerType = /*#__PURE__*/function (OwnerType) {\n OwnerType[OwnerType[\"OWNER_TYPE_INVALID\"] = 0] = \"OWNER_TYPE_INVALID\";\n OwnerType[OwnerType[\"OWNER_TYPE_PARTNER\"] = 1] = \"OWNER_TYPE_PARTNER\";\n OwnerType[OwnerType[\"OWNER_TYPE_ACCOUNT_GROUP\"] = 2] = \"OWNER_TYPE_ACCOUNT_GROUP\";\n OwnerType[OwnerType[\"OWNER_TYPE_SYSTEM\"] = 3] = \"OWNER_TYPE_SYSTEM\";\n return OwnerType;\n}(OwnerType || {});\n// *********************************\n\nfunction enumStringToValue$1(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass Access {\n static fromProto(proto) {\n let m = new Access();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.scope !== 'undefined') {\n toReturn['scope'] = this.scope;\n }\n if (typeof this.public !== 'undefined') {\n toReturn['public'] = this.public;\n }\n return toReturn;\n }\n}\nfunction enumStringToValue(enumRef, value) {\n if (typeof value === 'number') {\n return value;\n }\n return enumRef[value];\n}\nclass CreateEmailBuilderTemplateRequest {\n static fromProto(proto) {\n let m = new CreateEmailBuilderTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.ownerType) {\n m.ownerType = enumStringToValue(OwnerType, proto.ownerType);\n }\n if (proto.parent) {\n m.parent = TemplateReference.fromProto(proto.parent);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.ownerType !== 'undefined') {\n toReturn['ownerType'] = this.ownerType;\n }\n if (typeof this.ownerId !== 'undefined') {\n toReturn['ownerId'] = this.ownerId;\n }\n if (typeof this.appNamespace !== 'undefined') {\n toReturn['appNamespace'] = this.appNamespace;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.templateDisplayName !== 'undefined') {\n toReturn['templateDisplayName'] = this.templateDisplayName;\n }\n if (typeof this.templateJson !== 'undefined') {\n toReturn['templateJson'] = this.templateJson;\n }\n if (typeof this.templateHtml !== 'undefined') {\n toReturn['templateHtml'] = this.templateHtml;\n }\n if (typeof this.templateSubject !== 'undefined') {\n toReturn['templateSubject'] = this.templateSubject;\n }\n if (typeof this.parent !== 'undefined' && this.parent !== null) {\n toReturn['parent'] = 'toApiJson' in this.parent ? this.parent.toApiJson() : this.parent;\n }\n return toReturn;\n }\n}\nclass DeleteEmailBuilderTemplateRequest {\n static fromProto(proto) {\n let m = new DeleteEmailBuilderTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.ownerType) {\n m.ownerType = enumStringToValue(OwnerType, proto.ownerType);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.ownerType !== 'undefined') {\n toReturn['ownerType'] = this.ownerType;\n }\n if (typeof this.ownerId !== 'undefined') {\n toReturn['ownerId'] = this.ownerId;\n }\n if (typeof this.appNamespace !== 'undefined') {\n toReturn['appNamespace'] = this.appNamespace;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n return toReturn;\n }\n}\nclass EmailBuilderTemplate {\n static fromProto(proto) {\n let m = new EmailBuilderTemplate();\n m = Object.assign(m, proto);\n if (proto.created) {\n m.created = new Date(proto.created);\n }\n if (proto.updated) {\n m.updated = new Date(proto.updated);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.templateDisplayName !== 'undefined') {\n toReturn['templateDisplayName'] = this.templateDisplayName;\n }\n if (typeof this.templateJson !== 'undefined') {\n toReturn['templateJson'] = this.templateJson;\n }\n if (typeof this.previewUrl !== 'undefined') {\n toReturn['previewUrl'] = this.previewUrl;\n }\n if (typeof this.created !== 'undefined' && this.created !== null) {\n toReturn['created'] = 'toApiJson' in this.created ? this.created.toApiJson() : this.created;\n }\n if (typeof this.updated !== 'undefined' && this.updated !== null) {\n toReturn['updated'] = 'toApiJson' in this.updated ? this.updated.toApiJson() : this.updated;\n }\n if (typeof this.templateHtml !== 'undefined') {\n toReturn['templateHtml'] = this.templateHtml;\n }\n if (typeof this.templateSubject !== 'undefined') {\n toReturn['templateSubject'] = this.templateSubject;\n }\n return toReturn;\n }\n}\nclass GetEmailBuilderTemplateRequest {\n static fromProto(proto) {\n let m = new GetEmailBuilderTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.ownerType) {\n m.ownerType = enumStringToValue(OwnerType, proto.ownerType);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.ownerType !== 'undefined') {\n toReturn['ownerType'] = this.ownerType;\n }\n if (typeof this.ownerId !== 'undefined') {\n toReturn['ownerId'] = this.ownerId;\n }\n if (typeof this.appNamespace !== 'undefined') {\n toReturn['appNamespace'] = this.appNamespace;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n return toReturn;\n }\n}\nclass GetEmailBuilderTemplateResponse {\n static fromProto(proto) {\n let m = new GetEmailBuilderTemplateResponse();\n m = Object.assign(m, proto);\n if (proto.template) {\n m.template = EmailBuilderTemplate.fromProto(proto.template);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.template !== 'undefined' && this.template !== null) {\n toReturn['template'] = 'toApiJson' in this.template ? this.template.toApiJson() : this.template;\n }\n return toReturn;\n }\n}\nclass GetEmailBuilderTemplatesRequest {\n static fromProto(proto) {\n let m = new GetEmailBuilderTemplatesRequest();\n m = Object.assign(m, proto);\n if (proto.ownerType) {\n m.ownerType = enumStringToValue(OwnerType, proto.ownerType);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.ownerType !== 'undefined') {\n toReturn['ownerType'] = this.ownerType;\n }\n if (typeof this.ownerId !== 'undefined') {\n toReturn['ownerId'] = this.ownerId;\n }\n if (typeof this.appNamespace !== 'undefined') {\n toReturn['appNamespace'] = this.appNamespace;\n }\n if (typeof this.templateIds !== 'undefined') {\n toReturn['templateIds'] = this.templateIds;\n }\n return toReturn;\n }\n}\nclass GetEmailBuilderTemplatesResponse {\n static fromProto(proto) {\n let m = new GetEmailBuilderTemplatesResponse();\n m = Object.assign(m, proto);\n if (proto.templates) {\n m.templates = proto.templates.map(EmailBuilderTemplate.fromProto);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templates !== 'undefined' && this.templates !== null) {\n toReturn['templates'] = 'toApiJson' in this.templates ? this.templates.toApiJson() : this.templates;\n }\n return toReturn;\n }\n}\nclass ListEmailBuilderTemplatesRequest {\n static fromProto(proto) {\n let m = new ListEmailBuilderTemplatesRequest();\n m = Object.assign(m, proto);\n if (proto.ownerType) {\n m.ownerType = enumStringToValue(OwnerType, proto.ownerType);\n }\n if (proto.pagingOptions) {\n m.pagingOptions = PagedRequestOptions.fromProto(proto.pagingOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.ownerType !== 'undefined') {\n toReturn['ownerType'] = this.ownerType;\n }\n if (typeof this.ownerId !== 'undefined') {\n toReturn['ownerId'] = this.ownerId;\n }\n if (typeof this.appNamespace !== 'undefined') {\n toReturn['appNamespace'] = this.appNamespace;\n }\n if (typeof this.searchTerm !== 'undefined') {\n toReturn['searchTerm'] = this.searchTerm;\n }\n if (typeof this.pagingOptions !== 'undefined' && this.pagingOptions !== null) {\n toReturn['pagingOptions'] = 'toApiJson' in this.pagingOptions ? this.pagingOptions.toApiJson() : this.pagingOptions;\n }\n return toReturn;\n }\n}\nclass ListEmailBuilderTemplatesResponse {\n static fromProto(proto) {\n let m = new ListEmailBuilderTemplatesResponse();\n m = Object.assign(m, proto);\n if (proto.templates) {\n m.templates = proto.templates.map(EmailBuilderTemplate.fromProto);\n }\n if (proto.pagingMetadata) {\n m.pagingMetadata = PagedResponseMetadata.fromProto(proto.pagingMetadata);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templates !== 'undefined' && this.templates !== null) {\n toReturn['templates'] = 'toApiJson' in this.templates ? this.templates.toApiJson() : this.templates;\n }\n if (typeof this.pagingMetadata !== 'undefined' && this.pagingMetadata !== null) {\n toReturn['pagingMetadata'] = 'toApiJson' in this.pagingMetadata ? this.pagingMetadata.toApiJson() : this.pagingMetadata;\n }\n return toReturn;\n }\n}\nclass PagedRequestOptions {\n static fromProto(proto) {\n let m = new PagedRequestOptions();\n m = Object.assign(m, proto);\n if (proto.pageSize) {\n m.pageSize = parseInt(proto.pageSize, 10);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.cursor !== 'undefined') {\n toReturn['cursor'] = this.cursor;\n }\n if (typeof this.pageSize !== 'undefined') {\n toReturn['pageSize'] = this.pageSize;\n }\n return toReturn;\n }\n}\nclass PagedResponseMetadata {\n static fromProto(proto) {\n let m = new PagedResponseMetadata();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.nextCursor !== 'undefined') {\n toReturn['nextCursor'] = this.nextCursor;\n }\n if (typeof this.hasMore !== 'undefined') {\n toReturn['hasMore'] = this.hasMore;\n }\n return toReturn;\n }\n}\nclass SearchEmailBuilderTemplatesRequest {\n static fromProto(proto) {\n let m = new SearchEmailBuilderTemplatesRequest();\n m = Object.assign(m, proto);\n if (proto.ownerType) {\n m.ownerType = enumStringToValue(OwnerType, proto.ownerType);\n }\n if (proto.pagingOptions) {\n m.pagingOptions = PagedRequestOptions.fromProto(proto.pagingOptions);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.ownerType !== 'undefined') {\n toReturn['ownerType'] = this.ownerType;\n }\n if (typeof this.ownerId !== 'undefined') {\n toReturn['ownerId'] = this.ownerId;\n }\n if (typeof this.appNamespace !== 'undefined') {\n toReturn['appNamespace'] = this.appNamespace;\n }\n if (typeof this.searchTerm !== 'undefined') {\n toReturn['searchTerm'] = this.searchTerm;\n }\n if (typeof this.pagingOptions !== 'undefined' && this.pagingOptions !== null) {\n toReturn['pagingOptions'] = 'toApiJson' in this.pagingOptions ? this.pagingOptions.toApiJson() : this.pagingOptions;\n }\n return toReturn;\n }\n}\nclass SearchEmailBuilderTemplatesResponse {\n static fromProto(proto) {\n let m = new SearchEmailBuilderTemplatesResponse();\n m = Object.assign(m, proto);\n if (proto.templates) {\n m.templates = proto.templates.map(EmailBuilderTemplate.fromProto);\n }\n if (proto.pagingMetadata) {\n m.pagingMetadata = PagedResponseMetadata.fromProto(proto.pagingMetadata);\n }\n if (proto.hits) {\n m.hits = parseInt(proto.hits, 10);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.templates !== 'undefined' && this.templates !== null) {\n toReturn['templates'] = 'toApiJson' in this.templates ? this.templates.toApiJson() : this.templates;\n }\n if (typeof this.pagingMetadata !== 'undefined' && this.pagingMetadata !== null) {\n toReturn['pagingMetadata'] = 'toApiJson' in this.pagingMetadata ? this.pagingMetadata.toApiJson() : this.pagingMetadata;\n }\n if (typeof this.hits !== 'undefined') {\n toReturn['hits'] = this.hits;\n }\n return toReturn;\n }\n}\nclass SuggestContentRequest {\n static fromProto(proto) {\n let m = new SuggestContentRequest();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.prompt !== 'undefined') {\n toReturn['prompt'] = this.prompt;\n }\n return toReturn;\n }\n}\nclass SuggestContentResponse {\n static fromProto(proto) {\n let m = new SuggestContentResponse();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.message !== 'undefined') {\n toReturn['message'] = this.message;\n }\n return toReturn;\n }\n}\nclass TemplateReference {\n static fromProto(proto) {\n let m = new TemplateReference();\n m = Object.assign(m, proto);\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.appNamespace !== 'undefined') {\n toReturn['appNamespace'] = this.appNamespace;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n return toReturn;\n }\n}\nclass UpdateEmailBuilderTemplateRequest {\n static fromProto(proto) {\n let m = new UpdateEmailBuilderTemplateRequest();\n m = Object.assign(m, proto);\n if (proto.ownerType) {\n m.ownerType = enumStringToValue(OwnerType, proto.ownerType);\n }\n return m;\n }\n constructor(kwargs) {\n if (!kwargs) {\n return;\n }\n Object.assign(this, kwargs);\n }\n toApiJson() {\n const toReturn = {};\n if (typeof this.ownerType !== 'undefined') {\n toReturn['ownerType'] = this.ownerType;\n }\n if (typeof this.ownerId !== 'undefined') {\n toReturn['ownerId'] = this.ownerId;\n }\n if (typeof this.appNamespace !== 'undefined') {\n toReturn['appNamespace'] = this.appNamespace;\n }\n if (typeof this.templateId !== 'undefined') {\n toReturn['templateId'] = this.templateId;\n }\n if (typeof this.templateDisplayName !== 'undefined') {\n toReturn['templateDisplayName'] = this.templateDisplayName;\n }\n if (typeof this.templateJson !== 'undefined') {\n toReturn['templateJson'] = this.templateJson;\n }\n if (typeof this.templateHtml !== 'undefined') {\n toReturn['templateHtml'] = this.templateHtml;\n }\n if (typeof this.templateSubject !== 'undefined') {\n toReturn['templateSubject'] = this.templateSubject;\n }\n return toReturn;\n }\n}\n\n// *********************************\n\nconst environment = (window ? window['environment'] : 'prod') ?? 'prod';\nconst hostMap = {\n 'local': 'email-builder-api.vendasta-local.com',\n 'test': '',\n 'demo': 'email-builder-demo.apigateway.co',\n 'prod': 'email-builder-prod.apigateway.co',\n 'production': 'email-builder-prod.apigateway.co'\n};\nlet HostService = /*#__PURE__*/(() => {\n class HostService {\n get host() {\n return hostMap[environment.toLowerCase()];\n }\n get hostWithScheme() {\n return 'https://' + this.host;\n }\n }\n HostService.ɵfac = function HostService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || HostService)();\n };\n HostService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: HostService,\n factory: HostService.ɵfac,\n providedIn: 'root'\n });\n return HostService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// *********************************\nlet ContentGenerationApiService = /*#__PURE__*/(() => {\n class ContentGenerationApiService {\n constructor(http, hostService) {\n this.http = http;\n this.hostService = hostService;\n this._host = this.hostService.hostWithScheme;\n }\n apiOptions() {\n return {\n headers: new HttpHeaders({\n 'Content-Type': 'application/json'\n }),\n withCredentials: true\n };\n }\n suggestContent(r) {\n const request = r.toApiJson ? r : new SuggestContentRequest(r);\n return this.http.post(this._host + \"/emailbuilder.v1.ContentGeneration/SuggestContent\", request.toApiJson(), this.apiOptions()).pipe(map(resp => SuggestContentResponse.fromProto(resp)));\n }\n }\n ContentGenerationApiService.ɵfac = function ContentGenerationApiService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || ContentGenerationApiService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(HostService));\n };\n ContentGenerationApiService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ContentGenerationApiService,\n factory: ContentGenerationApiService.ɵfac,\n providedIn: 'root'\n });\n return ContentGenerationApiService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// *********************************\nlet TemplatesApiService = /*#__PURE__*/(() => {\n class TemplatesApiService {\n constructor(http, hostService) {\n this.http = http;\n this.hostService = hostService;\n this._host = this.hostService.hostWithScheme;\n }\n apiOptions() {\n return {\n headers: new HttpHeaders({\n 'Content-Type': 'application/json'\n }),\n withCredentials: true\n };\n }\n createEmailBuilderTemplate(r) {\n const request = r.toApiJson ? r : new CreateEmailBuilderTemplateRequest(r);\n return this.http.post(this._host + \"/emailbuilder.v1.Templates/CreateEmailBuilderTemplate\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n updateEmailBuilderTemplate(r) {\n const request = r.toApiJson ? r : new UpdateEmailBuilderTemplateRequest(r);\n return this.http.post(this._host + \"/emailbuilder.v1.Templates/UpdateEmailBuilderTemplate\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n getEmailBuilderTemplate(r) {\n const request = r.toApiJson ? r : new GetEmailBuilderTemplateRequest(r);\n return this.http.post(this._host + \"/emailbuilder.v1.Templates/GetEmailBuilderTemplate\", request.toApiJson(), this.apiOptions()).pipe(map(resp => GetEmailBuilderTemplateResponse.fromProto(resp)));\n }\n getEmailBuilderTemplates(r) {\n const request = r.toApiJson ? r : new GetEmailBuilderTemplatesRequest(r);\n return this.http.post(this._host + \"/emailbuilder.v1.Templates/GetEmailBuilderTemplates\", request.toApiJson(), this.apiOptions()).pipe(map(resp => GetEmailBuilderTemplatesResponse.fromProto(resp)));\n }\n listEmailBuilderTemplates(r) {\n const request = r.toApiJson ? r : new ListEmailBuilderTemplatesRequest(r);\n return this.http.post(this._host + \"/emailbuilder.v1.Templates/ListEmailBuilderTemplates\", request.toApiJson(), this.apiOptions()).pipe(map(resp => ListEmailBuilderTemplatesResponse.fromProto(resp)));\n }\n deleteEmailBuilderTemplate(r) {\n const request = r.toApiJson ? r : new DeleteEmailBuilderTemplateRequest(r);\n return this.http.post(this._host + \"/emailbuilder.v1.Templates/DeleteEmailBuilderTemplate\", request.toApiJson(), {\n ...this.apiOptions(),\n observe: 'response'\n });\n }\n searchEmailBuilderTemplates(r) {\n const request = r.toApiJson ? r : new SearchEmailBuilderTemplatesRequest(r);\n return this.http.post(this._host + \"/emailbuilder.v1.Templates/SearchEmailBuilderTemplates\", request.toApiJson(), this.apiOptions()).pipe(map(resp => SearchEmailBuilderTemplatesResponse.fromProto(resp)));\n }\n }\n TemplatesApiService.ɵfac = function TemplatesApiService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || TemplatesApiService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(HostService));\n };\n TemplatesApiService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: TemplatesApiService,\n factory: TemplatesApiService.ɵfac,\n providedIn: 'root'\n });\n return TemplatesApiService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n// *********************************\n\nvar AppNamespace = /*#__PURE__*/function (AppNamespace) {\n AppNamespace[\"DEV_SANDBOX\"] = \"developer_sandbox\";\n AppNamespace[\"CAMPAIGNS\"] = \"campaigns\";\n AppNamespace[\"AUTOMATIONS\"] = \"automations\";\n AppNamespace[\"EMAIL_LIBRARY\"] = \"email_library\";\n AppNamespace[\"REPUTATION_REVIEW_REQUEST\"] = \"reputation_management/review_request\";\n return AppNamespace;\n}(AppNamespace || {});\nlet TemplatesService = /*#__PURE__*/(() => {\n class TemplatesService {\n constructor(api) {\n this.api = api;\n }\n createNewTemplate(ownerType, ownerId, appNamespace, templateId, templateDisplayName, templateJSON, templateHTML, templateSubject, parent) {\n const req = new CreateEmailBuilderTemplateRequest({\n ownerType: ownerType,\n ownerId: ownerId,\n appNamespace: appNamespace,\n templateId: templateId,\n templateDisplayName: templateDisplayName,\n templateJson: templateJSON,\n templateHtml: templateHTML,\n templateSubject: templateSubject,\n parent: parent\n });\n return this.api.createEmailBuilderTemplate(req).pipe(map(() => null));\n }\n updateExistingTemplate(ownerType, ownerId, appNamespace, templateId, templateDisplayName, templateJSON, templateHTML, templateSubject) {\n const req = new UpdateEmailBuilderTemplateRequest({\n ownerType: ownerType,\n ownerId: ownerId,\n appNamespace: appNamespace,\n templateId: templateId,\n templateDisplayName: templateDisplayName,\n templateJson: templateJSON,\n templateHtml: templateHTML,\n templateSubject: templateSubject\n });\n return this.api.updateEmailBuilderTemplate(req).pipe(map(() => null));\n }\n getTemplate(ownerType, ownerId, appNamespace, templateId) {\n const req = new GetEmailBuilderTemplateRequest({\n ownerType: ownerType,\n ownerId: ownerId,\n appNamespace: appNamespace,\n templateId: templateId\n });\n return this.api.getEmailBuilderTemplate(req).pipe(map(resp => resp.template));\n }\n getTemplates(ownerType, ownerId, appNamespace, templateIds) {\n const req = new GetEmailBuilderTemplatesRequest({\n ownerType: ownerType,\n ownerId: ownerId,\n appNamespace: appNamespace,\n templateIds: templateIds\n });\n return this.api.getEmailBuilderTemplates(req).pipe(map(resp => resp.templates));\n }\n getTemplateHTML(ownerType, ownerId, appNamespace, templateId) {\n const req = new GetEmailBuilderTemplateRequest({\n ownerType: ownerType,\n ownerId: ownerId,\n appNamespace: appNamespace,\n templateId: templateId\n });\n return this.api.getEmailBuilderTemplate(req).pipe(map(resp => resp?.template?.templateHtml));\n }\n listTemplates(ownerType, ownerId, appNamespace, searchTerm, cursor, pageSize) {\n const req = new ListEmailBuilderTemplatesRequest({\n ownerType: ownerType,\n ownerId: ownerId,\n appNamespace: appNamespace,\n searchTerm: searchTerm,\n pagingOptions: {\n cursor: cursor,\n pageSize: pageSize\n }\n });\n return this.api.listEmailBuilderTemplates(req).pipe(map(v => {\n v.templates = v.templates || [];\n return v;\n }));\n }\n searchTemplates(ownerType, ownerId, appNamespace, searchTerm, pageSize, cursor) {\n const req = new SearchEmailBuilderTemplatesRequest({\n ownerType: ownerType,\n ownerId: ownerId,\n appNamespace: appNamespace,\n searchTerm: searchTerm,\n pagingOptions: new PagedRequestOptions({\n cursor: cursor,\n pageSize: pageSize\n })\n });\n return this.api.searchEmailBuilderTemplates(req).pipe(map(v => {\n v.templates = v.templates || [];\n return v;\n }));\n }\n deleteTemplate(ownerType, ownerId, appNamespace, templateId) {\n const req = new DeleteEmailBuilderTemplateRequest({\n ownerType: ownerType,\n ownerId: ownerId,\n appNamespace: appNamespace,\n templateId: templateId\n });\n return this.api.deleteEmailBuilderTemplate(req);\n }\n }\n TemplatesService.ɵfac = function TemplatesService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || TemplatesService)(i0.ɵɵinject(TemplatesApiService));\n };\n TemplatesService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: TemplatesService,\n factory: TemplatesService.ɵfac,\n providedIn: 'root'\n });\n return TemplatesService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\nlet ContentGenerationService = /*#__PURE__*/(() => {\n class ContentGenerationService {\n constructor(api) {\n this.api = api;\n }\n suggestContent(prompt) {\n const req = new SuggestContentRequest({\n prompt: prompt\n });\n return this.api.suggestContent(req).pipe(map(resp => resp.message));\n }\n }\n ContentGenerationService.ɵfac = function ContentGenerationService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || ContentGenerationService)(i0.ɵɵinject(ContentGenerationApiService));\n };\n ContentGenerationService.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ContentGenerationService,\n factory: ContentGenerationService.ɵfac,\n providedIn: 'root'\n });\n return ContentGenerationService;\n})();\n(() => {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { Access, AppNamespace, ContentGenerationService, CreateEmailBuilderTemplateRequest, DeleteEmailBuilderTemplateRequest, EmailBuilderTemplate, GetEmailBuilderTemplateRequest, GetEmailBuilderTemplateResponse, GetEmailBuilderTemplatesRequest, GetEmailBuilderTemplatesResponse, ListEmailBuilderTemplatesRequest, ListEmailBuilderTemplatesResponse, OwnerType, PagedRequestOptions, PagedResponseMetadata, SearchEmailBuilderTemplatesRequest, SearchEmailBuilderTemplatesResponse, SuggestContentRequest, SuggestContentResponse, TemplateReference, TemplatesService, UpdateEmailBuilderTemplateRequest };\n","import { Inject, Injectable, Optional } from '@angular/core';\nimport { ActivatableApp } from '@vendasta/marketplace-packages';\nimport {\n ListSubstitutionParametersRequestFiltersInterface,\n SubstitutionParameter,\n TemplatesService,\n} from '@vendasta/templates';\nimport { Observable, of } from 'rxjs';\nimport { catchError, map, shareReplay, switchMap, take } from 'rxjs/operators';\nimport {\n AppListingServiceInterface,\n EMAIL_BUILDER_APP_LISTING_SERVICE_TOKEN,\n} from '../../services/app-listing-service.interface';\nimport { ListFieldSchemaResponse } from '@vendasta/crm/lib/_internal/objects';\nimport { CRMFieldSchemaApiService } from '@vendasta/crm';\nimport { SENDER_ID_TOKEN } from '../../../../email-activity/src/dependencies';\n\nexport interface Option {\n title: string;\n value: string;\n}\n\nexport interface VariableMenuItemOptions {\n requiredParams: string[];\n nestedDynamicSelector: boolean;\n}\n\nexport interface VariableMenuItem {\n textKey: string;\n replacementTags?: string[];\n replacementTag?: string;\n template?: string;\n subItems?: SubstitutionParameter[];\n options?: VariableMenuItemOptions;\n}\n\n@Injectable()\nexport class DynamicComponentSelectorService {\n private parentVariableCategories: VariableMenuItem[] = [];\n private initialCategories: VariableMenuItem[] = [];\n constructor(\n private readonly crmFieldSchemaApiService: CRMFieldSchemaApiService,\n private readonly templatesService: TemplatesService,\n @Inject(EMAIL_BUILDER_APP_LISTING_SERVICE_TOKEN) @Optional() private appListingService: AppListingServiceInterface,\n @Inject(SENDER_ID_TOKEN) private senderId$: Observable,\n ) {}\n\n public hasComponentsToDisplay(): boolean {\n return this.parentVariableCategories.length > 0;\n }\n\n public getVariables(filters: ListSubstitutionParametersRequestFiltersInterface): Observable {\n return this.templatesService\n .listSubstitutionParameters(filters)\n .pipe(map((params) => this.processCategories(params)));\n }\n\n private processCategories(params: SubstitutionParameter[]): VariableMenuItem[] {\n const initialCategories = this.getInitialCategories();\n const categories = this.filterSubstitutionParameters(params, initialCategories);\n return this.processSubItems(categories);\n }\n\n private filterSubstitutionParameters(\n params: SubstitutionParameter[],\n categories: VariableMenuItem[],\n ): VariableMenuItem[] {\n return categories.map((v) => ({\n textKey: v.textKey,\n replacementTags: v.replacementTags,\n options: v.options,\n subItems: params\n .filter((p) => v.replacementTags.some((t) => t === p.replacementTag))\n .sort(function (a, b): number {\n return v.replacementTags.indexOf(a.replacementTag) - v.replacementTags.indexOf(b.replacementTag);\n }),\n }));\n }\n\n private initializeCategories(parentCategories: VariableMenuItem[]): void {\n if (!this.initialCategories.length) {\n this.initialCategories = JSON.parse(JSON.stringify(parentCategories));\n }\n }\n\n private processSubItems(parentCategories: VariableMenuItem[]): VariableMenuItem[] {\n const processFields = (\n parentCategories: VariableMenuItem[],\n textKey: string,\n fields$: Observable,\n ) => {\n fields$.pipe(take(1)).subscribe((fields) => {\n const category = parentCategories.find((v) => v.textKey === textKey);\n if (!category || !category.options?.nestedDynamicSelector) {\n return;\n }\n category.replacementTags = category.replacementTags.reduce((acc, tag) => {\n return acc.concat(fields.map((field) => `${tag}['${field.replacementTag}']`));\n }, []);\n\n category.subItems = fields.map((field) => {\n const matchingTag = category.replacementTags.find((tag) => tag.includes(field.replacementTag));\n return {\n replacementTag: matchingTag,\n displayName: field.textKey,\n } as SubstitutionParameter;\n });\n\n category.options.nestedDynamicSelector = false;\n });\n };\n\n const companyTextKey = 'EMAIL_BUILDER.DYNAMIC_COMPONENT_SELECTOR.PRIMARY_COMPANY_DETAILS';\n const contactTextKey = 'EMAIL_BUILDER.DYNAMIC_COMPONENT_SELECTOR.CONTACT_DETAILS';\n\n processFields(parentCategories, companyTextKey, this.getCRMPrimaryCompanyFields$());\n processFields(parentCategories, contactTextKey, this.getCRMContactFields$());\n\n return parentCategories;\n }\n\n public getProductSubstitutionVariables(): Observable {\n return this.appListingService.listAllActivatableApps().pipe(take(1));\n }\n\n public overrideParentVariableCategories(variableCategories: VariableMenuItem[]): VariableMenuItem[] {\n this.initializeCategories(variableCategories);\n return (this.parentVariableCategories = variableCategories);\n }\n\n public getCRMContactFields$(): Observable {\n return this.senderId$.pipe(\n switchMap((namespace) => {\n return this.crmFieldSchemaApiService\n .listFieldSchema({\n namespace: namespace,\n crmObjectType: 'Contact',\n pagingOptions: { pageSize: 200 },\n })\n .pipe(\n map((response: ListFieldSchemaResponse) => response.fieldSchemas || []),\n map((fieldSchemas) => {\n return fieldSchemas.map(\n (schema): VariableMenuItem => ({\n textKey: schema.fieldName,\n replacementTag: \"__Contact_ID__', '\" + schema.fieldId,\n }),\n );\n }),\n map((items: VariableMenuItem[]) => items.sort((a, b) => a.textKey.localeCompare(b.textKey))),\n catchError((err) => {\n console.error(err);\n return of([]);\n }),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n }),\n );\n }\n\n public getCRMPrimaryCompanyFields$(): Observable {\n return this.senderId$.pipe(\n switchMap((namespace) => {\n return this.crmFieldSchemaApiService\n .listFieldSchema({\n namespace: namespace,\n crmObjectType: 'Contact',\n pagingOptions: { pageSize: 200 },\n })\n .pipe(\n map((response: ListFieldSchemaResponse) => response.fieldSchemas || []),\n switchMap(() => {\n return this.crmFieldSchemaApiService\n .listFieldSchema({\n namespace: namespace,\n crmObjectType: 'Company',\n pagingOptions: { pageSize: 200 },\n })\n .pipe(\n map((response: ListFieldSchemaResponse) => response.fieldSchemas || []),\n map((fieldSchemas) => {\n return fieldSchemas.map(\n (schema): VariableMenuItem => ({\n textKey: schema.fieldName,\n replacementTag: \"__Contact_ID__', '\" + schema.fieldId,\n }),\n );\n }),\n map((items: VariableMenuItem[]) => items.sort((a, b) => a.textKey.localeCompare(b.textKey))),\n catchError((err) => {\n console.error(err);\n return of([]);\n }),\n );\n }),\n shareReplay({ bufferSize: 1, refCount: true }),\n );\n }),\n );\n }\n\n private getInitialCategories(): VariableMenuItem[] {\n return JSON.parse(JSON.stringify(this.initialCategories));\n }\n}\n","import {\n Component,\n computed,\n DestroyRef,\n EventEmitter,\n OnInit,\n Output,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { DynamicComponentSelectorService, Option, VariableMenuItem } from '../dynamic-component-selector.service';\nimport { Observable, of, ReplaySubject } from 'rxjs';\nimport { map, shareReplay, startWith, switchMap } from 'rxjs/operators';\nimport { SubstitutionParameter } from '@vendasta/templates';\nimport { MatDialogRef } from '@angular/material/dialog';\nimport { UntypedFormControl } from '@angular/forms';\nimport { TranslateService } from '@ngx-translate/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Component({\n selector: 'email-dynamic-component-dialog',\n templateUrl: './dynamic-component-dialog.component.html',\n styleUrls: ['./dynamic-component-dialog.component.scss'],\n standalone: false,\n})\nexport class DynamicComponentDialogComponent implements OnInit {\n @Output() formResult: EventEmitter = new EventEmitter();\n private readonly allowedEntryApps = ['RM', 'SM'];\n\n variables$: Observable = this.dynamicComponentSelectorService\n .getVariables({ includeHtml: true })\n .pipe(\n map((vars) => {\n return vars.filter((v) => {\n return (v?.options?.requiredParams || []).reduce((prev, _, i, arr) => {\n return prev && !!this[arr[i]];\n }, true);\n });\n }),\n shareReplay(1),\n );\n protected disabled: WritableSignal = signal(true);\n\n protected chosenCategory: WritableSignal = signal(null);\n protected chosenParam: WritableSignal = signal(null);\n protected chosenParamDetails: WritableSignal = signal('');\n\n protected chosenDynamicParam$$ = new ReplaySubject(1);\n protected chosenDynamicParam$: Observable;\n\n protected categoryControl = new UntypedFormControl();\n protected paramControl = new UntypedFormControl();\n protected paramDetailsControl = new UntypedFormControl();\n\n protected filteredCategories$: Observable;\n protected filteredParams: Signal;\n protected filteredParamDetails$: Observable;\n\n constructor(\n private readonly dynamicComponentSelectorService: DynamicComponentSelectorService,\n public dialogRef: MatDialogRef,\n private readonly translate: TranslateService,\n private destroyRef: DestroyRef,\n ) {}\n\n ngOnInit(): void {\n this.categoryControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef), startWith('')).subscribe((value) => {\n this.filterCategories(value);\n });\n\n this.paramControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef), startWith('')).subscribe((value) => {\n this.filterParams(value);\n });\n\n this.chosenDynamicParam$ = this.chosenDynamicParam$$.asObservable().pipe(\n switchMap((chosenDynamicParam) => {\n if (\n chosenDynamicParam === 'productName' ||\n chosenDynamicParam === 'productPreviewUrl' ||\n chosenDynamicParam === 'productUrl'\n ) {\n return this.dynamicComponentSelectorService.getProductSubstitutionVariables().pipe(\n map((apps) => {\n if (chosenDynamicParam === 'productUrl') {\n apps = apps.filter((a) => this.allowedEntryApps.includes(a.appId));\n }\n return apps.map((app) => {\n return {\n title: app.name,\n value: app.appId,\n };\n });\n }),\n );\n } else {\n return of([]);\n }\n }),\n );\n\n this.paramDetailsControl.valueChanges\n .pipe(takeUntilDestroyed(this.destroyRef), startWith(''))\n .subscribe((value) => {\n this.filterParamDetails(value);\n });\n }\n\n protected filterCategories(value?: VariableMenuItem): void {\n const query = (value?.textKey || this.categoryControl.value || '').toLowerCase();\n this.filteredCategories$ = this.variables$.pipe(\n map((vars) => vars.filter((v) => v.textKey.toLowerCase().includes(query))),\n );\n }\n\n protected filterParams(value?: SubstitutionParameter): void {\n const query = (value?.displayName || this.paramControl.value || '').toLowerCase();\n this.filteredParams = computed(() =>\n this.chosenCategory()?.subItems.filter((v) => v.displayName.toLowerCase().includes(query)),\n );\n }\n\n protected filterParamDetails(value?: Option): void {\n const query = (value?.title || this.paramDetailsControl.value || '').toLowerCase();\n this.filteredParamDetails$ = this.chosenDynamicParam$.pipe(\n map((vars) => vars.filter((v) => v.title.toLowerCase().includes(query))),\n );\n }\n\n protected handleCategoryChange(category: VariableMenuItem): void {\n this.chosenCategory.set(category);\n this.chosenParam.set(null);\n this.paramControl.setValue('');\n this.chosenParamDetails.set('');\n }\n\n protected handleParamChange(param: SubstitutionParameter): void {\n this.chosenParam.set(param);\n this.chosenParamDetails.set('');\n this.paramDetailsControl.setValue('');\n if (\n this.chosenParam().replacementTag === 'productName' ||\n this.chosenParam().replacementTag === 'productPreviewUrl' ||\n this.chosenParam().replacementTag === 'productUrl'\n ) {\n this.chosenDynamicParam$$.next(this.chosenParam().replacementTag);\n this.disabled.set(true);\n } else {\n this.disabled.set(false);\n }\n }\n\n protected handleParamDetailsChange(paramDetails: Option): void {\n this.chosenParamDetails.set(paramDetails.value);\n this.disabled.set(false);\n }\n\n add(): void {\n let replacementTag = this.chosenParam().replacementTag;\n if (this.chosenParamDetails()) {\n replacementTag = `${replacementTag}['${this.chosenParamDetails()}']`;\n }\n this.dialogRef.close('{{ ' + replacementTag + ' }}');\n }\n\n protected categoryDisplayName(category: VariableMenuItem): string {\n return category ? this.translate.instant(category.textKey) : '';\n }\n\n protected paramDisplayName(param: SubstitutionParameter): string {\n return param ? param.displayName : '';\n }\n\n protected paramDetailsDisplayName(paramDetails: Option): string {\n return paramDetails ? paramDetails.title : '';\n }\n\n close(): void {\n this.dialogRef.close(null);\n }\n}\n","

{{ 'EMAIL_BUILDER.DYNAMIC_COMPONENT_DIALOG.ADD_HEADING' | translate }}

\n\n\n @if (variables$ | async) {\n \n {{ 'EMAIL_BUILDER.DYNAMIC_COMPONENT_DIALOG.CATEGORY' | translate }}\n \n \n @for (category of filteredCategories$ | async; track category) {\n \n {{ category.textKey | translate }}\n \n }\n \n \n @if (chosenCategory() !== null) {\n \n {{ chosenCategory().textKey | translate }}\n \n \n @for (param of filteredParams(); track param) {\n \n {{ param.displayName | translate }}\n \n }\n \n \n }\n @if (chosenCategory() !== null && chosenParam() !== null && chosenCategory()?.options?.nestedDynamicSelector) {\n @if (chosenDynamicParam$ | async) {\n \n {{ chosenParam().displayName | translate }}\n \n \n @for (paramDetail of filteredParamDetails$ | async; track paramDetail) {\n \n {{ paramDetail.title | translate }}\n \n }\n \n \n } @else {\n
\n }\n }\n } @else {\n \n \n {{ 'EMAIL_BUILDER.DYNAMIC_COMPONENT_DIALOG.NO_OPTIONS' | translate }}\n \n \n }\n
\n\n\n
\n \n \n
\n
\n","import 'tinymce/icons/default';\nimport 'tinymce/themes/silver';\n\nimport {\n AfterViewInit,\n Component,\n ElementRef,\n EventEmitter,\n HostBinding,\n Input,\n OnDestroy,\n Output,\n ViewChild,\n} from '@angular/core';\nimport { UntypedFormControl, ValidationErrors } from '@angular/forms';\nimport { Validator } from '@vendasta/shared';\nimport { Subscription } from 'rxjs';\n\ndeclare let tinymce: any;\n\n// If we want to turn this into a proper input\n// https://blog.angular-university.io/angular-custom-form-controls/\n\nconst tinyMCEHyperlinkTextColour = '#057EC1';\n\n@Component({\n selector: 'email-rich-text-editor',\n templateUrl: './rich-text-editor.component.html',\n styleUrls: ['./rich-text-editor.component.scss'],\n standalone: false,\n})\nexport class RichTextEditorComponent implements AfterViewInit, OnDestroy {\n @HostBinding('class') class = 'email-rich-text-editor';\n\n @ViewChild('richEditorDiv') richEditorDiv: ElementRef;\n\n @Input() disabled: boolean;\n @Input() menubar: any = false;\n @Input() menu: any = false;\n @Input() toolbar: string[] = [\n 'bold italic link unlink | alignleft aligncenter alignright | bullist numlist | code removeformat',\n ];\n @Input() plugins = 'lists link code image';\n @Input() width: number;\n @Input() height: string | number = '100%';\n // This is for uploading images\n @Input() showUploadTab = false;\n @Input() invalidElements: string;\n\n @Input() set value(value: string) {\n this._value = value;\n }\n @Output() valueChange: EventEmitter = new EventEmitter();\n @Output() statusChange: EventEmitter = new EventEmitter();\n\n _value: string;\n editorIsReady = false;\n\n private editor: any;\n private subscriptions: Subscription[] = [];\n\n theme =\n window.getComputedStyle(document.documentElement).getPropertyValue('--is-dark-theme') === 'true' ? 'dark' : 'light';\n\n ngAfterViewInit(): void {\n this.subscriptions.push(\n this.valueChange.subscribe((value) => {\n if (value !== '') {\n const isValid = Validator.containsValidDynamicContent({ value: value } as UntypedFormControl);\n this.statusChange.emit(isValid);\n }\n }),\n );\n // using setTimeout as a hack to make sure everything is\n // ready before loading\n window.setTimeout(() => {\n this.setupEditor();\n }, 0);\n }\n\n ngOnDestroy(): void {\n tinymce.remove(this.editor);\n this.subscriptions.forEach((subscription) => {\n subscription.unsubscribe();\n });\n }\n\n onEditorChange(): void {\n if (!this.editor) {\n return;\n }\n const newContent = this.editor.getContent();\n if (newContent === this._value) {\n return;\n } else {\n this.valueChange.emit(newContent);\n this._value = newContent;\n }\n }\n\n public reloadEditor(): void {\n console.log('reloadEditor');\n tinymce.remove(this.editor);\n window.setTimeout(() => {\n this.setupEditor();\n }, 0);\n }\n\n insertAtCursor(text: string): void {\n this.editor.insertContent(text);\n }\n\n focus(): void {\n this.richEditorDiv.nativeElement.focus();\n }\n\n setupEditor(): void {\n tinymce.baseURL = 'https://storage.googleapis.com/developers-vendasta-client/assets';\n tinymce.init({\n browser_spellcheck: true,\n content_style: `a {color: ${tinyMCEHyperlinkTextColour}`,\n skin: this.theme === 'dark' ? 'oxide-dark' : 'oxide',\n content_css: this.theme === 'dark' ? 'dark' : 'default',\n target: this.richEditorDiv.nativeElement,\n // selector: '#' + this.elementId,\n readonly: this.disabled,\n width: this.width,\n height: this.height,\n menubar: this.menubar,\n menu: this.menu,\n toolbar: this.toolbar,\n plugins: this.plugins,\n convert_urls: false,\n allow_conditional_comments: true,\n valid_children: '+body[style]',\n invalid_elements: this.invalidElements || null,\n branding: false,\n setup: (editor) => {\n this.editor = editor;\n editor.on('init', () => {\n this.editor.setContent(this._value);\n });\n // prevents this.editor from being undefined on events\n const updateHandler = () => {\n this.onEditorChange();\n };\n editor.on('keyup', updateHandler);\n editor.on('change', updateHandler);\n editor.on('NodeChange', updateHandler);\n },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n images_upload_handler: function (blobInfo: any, success: any, failure: any): void {\n //\n },\n images_upload_url: this.showUploadTab ? 'any-non-empty-value' : '',\n init_instance_callback: () => {\n this.editorIsReady = true;\n },\n });\n }\n}\n","\n\n@if (!editorIsReady) {\n
\n \n
\n}\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { take } from 'rxjs/operators';\nimport { DynamicComponentDialogComponent } from './dynamic-component-dialog/dynamic-component-dialog.component';\nimport { RichTextEditorComponent } from '../rich-text-editor/rich-text-editor.component';\nimport { DynamicComponentSelectorService } from './dynamic-component-selector.service';\n\n@Component({\n selector: 'email-dynamic-component-selector',\n templateUrl: 'dynamic-component-selector.component.html',\n styleUrls: ['dynamic-component-selector.component.scss'],\n standalone: false,\n})\nexport class DynamicComponentSelectorComponent {\n @Input() marketId: string;\n @Input() target: HTMLInputElement;\n @Input() model: string;\n @Input() richTextEditorRef?: RichTextEditorComponent;\n\n @Output() modelChange: EventEmitter = new EventEmitter();\n\n public variablesReady = this.variableService.hasComponentsToDisplay();\n\n constructor(\n private dialog: MatDialog,\n private variableService: DynamicComponentSelectorService,\n ) {}\n\n openDialog(): void {\n const dialogRef = this.dialog.open(DynamicComponentDialogComponent, {\n autoFocus: false,\n width: '450px',\n height: '450px',\n });\n dialogRef\n .afterClosed()\n .pipe(take(1))\n .subscribe((res: string | null) => {\n if (res) {\n this.selectVariable(res);\n }\n });\n }\n\n selectVariable(replacementTag: string): void {\n if (this.richTextEditorRef) {\n this.richTextEditorRef.insertAtCursor(replacementTag);\n window.setTimeout(() => {\n this.richTextEditorRef.focus();\n }, 0);\n } else {\n const startPos = this.target.selectionStart;\n const endPos = this.target.selectionEnd ?? startPos;\n\n const contentBefore = this.target.value.substr(0, startPos);\n const contentAfter = this.target.value.substr(endPos, this.target.value.length);\n\n const newValue = contentBefore + replacementTag + contentAfter;\n this.target.value = newValue;\n this.target.selectionStart = startPos;\n\n this.modelChange.emit(newValue);\n\n // Using setTimeout fix bug where input does not focus\n window.setTimeout(() => {\n this.target.focus();\n this.target.setSelectionRange(startPos, replacementTag.length + startPos);\n }, 0);\n }\n }\n}\n","@if (variablesReady) {\n \n data_object\n \n}\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatOptionModule } from '@angular/material/core';\nimport { MatDialogModule } from '@angular/material/dialog';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatListModule } from '@angular/material/list';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatTooltipModule } from '@angular/material/tooltip';\n\nimport { TranslateModule } from '@ngx-translate/core';\n\nimport { GalaxyEmptyStateModule } from '@vendasta/galaxy/empty-state';\nimport { GalaxyWrapModule } from '@vendasta/galaxy/galaxy-wrap';\nimport { GalaxyTooltipModule } from '@vendasta/galaxy/tooltip';\n\nimport { DynamicComponentDialogComponent } from './dynamic-component-dialog/dynamic-component-dialog.component';\nimport { DynamicComponentSelectorComponent } from './dynamic-component-selector.component';\n\nimport {\n DynamicComponentSelectorService,\n Option,\n VariableMenuItem,\n VariableMenuItemOptions,\n} from './dynamic-component-selector.service';\nimport { EmailUII18nModule } from '../../../../src/lib/i18n/email-ui-i18n.module';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete';\nimport { GalaxyFormFieldModule } from '@vendasta/galaxy/form-field';\n\nexport { DynamicComponentSelectorService, VariableMenuItemOptions, VariableMenuItem, Option };\n\n@NgModule({\n providers: [DynamicComponentSelectorService],\n declarations: [DynamicComponentSelectorComponent, DynamicComponentDialogComponent],\n imports: [\n CommonModule,\n GalaxyTooltipModule,\n GalaxyWrapModule,\n MatFormFieldModule,\n MatButtonModule,\n MatDialogModule,\n MatInputModule,\n MatListModule,\n MatIconModule,\n MatTooltipModule,\n MatCardModule,\n MatOptionModule,\n TranslateModule,\n MatSelectModule,\n GalaxyEmptyStateModule,\n EmailUII18nModule,\n FormsModule,\n ReactiveFormsModule,\n MatAutocomplete,\n GalaxyFormFieldModule,\n MatAutocompleteTrigger,\n ],\n exports: [DynamicComponentSelectorComponent],\n})\nexport class DynamicComponentSelectorModule {}\n","export * from './dynamic-component-selector.module';\n","// Other drag and drop libraries:\n// https://github.com/valor-software/ng2-dragula\n// https://kutlugsahin.github.io/ngx-smooth-dnd/\n// https://angular-dnd-survey-creator.netlify.com/editor\n// https://github.com/angular/components/issues/14273\n\n// A more complex method to deep clone an object\n// https://stackoverflow.com/questions/28150967/typescript-cloning-object/28152032#28152032\nimport { inject, InjectionToken } from '@angular/core';\nimport { AccountGroup } from '@galaxy/account-group';\nimport { Sender, SenderType } from '@vendasta/email';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\n\n/**\n * A quick and dirty way to deep copy an object.\\\n * *Warning*: This will convert date types into strings\n * @param input - the object to duplicate.\n */\nexport function jsonCopy(input: object): object {\n return JSON.parse(JSON.stringify(input));\n}\n\nexport const SENDER_INJECTION_TOKEN: InjectionToken> = new InjectionToken(\n 'com.vendasta.email_builder.sender',\n);\n\nexport function buildSenderData(): Observable {\n const partnerID$ = inject('PARTNER_ID' as any, { optional: true }) as Observable;\n const accountGroup$ = inject('com.vendasta.bcc.account_group' as any, {\n optional: true,\n }) as Observable;\n const accountGroupID$ = inject('ACCOUNT_GROUP_ID' as any, { optional: true }) as Observable;\n\n if (accountGroup$) {\n return accountGroup$.pipe(\n map((agid) => {\n const sender = { type: SenderType.SENDER_TYPE_BUSINESS, id: agid.accountGroupId } as Sender;\n return sender;\n }),\n );\n } else if (accountGroupID$) {\n return accountGroupID$.pipe(\n map((agid) => {\n const sender = { type: SenderType.SENDER_TYPE_BUSINESS, id: agid } as Sender;\n return sender;\n }),\n );\n } else if (partnerID$) {\n return partnerID$.pipe(\n map((pid) => {\n const sender = { type: SenderType.SENDER_TYPE_PARTNER, id: pid } as Sender;\n return sender;\n }),\n );\n }\n\n throw new Error('Expected one of partner ID or account group');\n}\n","import { AfterViewInit, Component, Inject, ViewChild } from '@angular/core';\nimport { NgForm } from '@angular/forms';\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { CrmFieldService, StandardExternalIds } from '@galaxy/crm/static';\nimport { CRMApiService, CrmObject, CrmObjectSearch, ListCrmObjectsRequest } from '@vendasta/crm';\nimport { Observable, combineLatest } from 'rxjs';\nimport { map, startWith, switchMap } from 'rxjs/operators';\n\nexport interface ContactData {\n contactID: string;\n accountGroupID: string;\n name: string;\n}\n\nexport interface DialogData {\n accountGroupID: string;\n}\n\n@Component({\n templateUrl: './contact-selector.component.html',\n styleUrls: ['./contact-selector.component.scss'],\n standalone: false,\n})\nexport class ContactSelectorComponent implements AfterViewInit {\n public contacts$: Observable;\n @ViewChild('search') search: NgForm;\n public searchTerm = '';\n\n constructor(\n private readonly dialogRef: MatDialogRef,\n @Inject(MAT_DIALOG_DATA) readonly data$: Observable,\n private readonly crmService: CRMApiService,\n private readonly crmFieldService: CrmFieldService,\n ) {}\n\n ngAfterViewInit(): void {\n this.contacts$ = combineLatest([this.data$, this.search.form.valueChanges.pipe(startWith(''))]).pipe(\n switchMap(([data]) =>\n this.crmService\n .listContacts({\n namespace: data.accountGroupID,\n search: { searchTerm: this.searchTerm } as CrmObjectSearch,\n pagingOptions: {\n pageSize: 20,\n },\n } as ListCrmObjectsRequest)\n .pipe(map((response) => ({ contacts: response.crmObjects, accountGroupId: data.accountGroupID }))),\n ),\n map((response) => {\n let contacts = response?.contacts?.map((contact: CrmObject) => ({\n name: this.getNameForContact(contact),\n accountGroupID: response.accountGroupId,\n contactID: contact.crmObjectId,\n })) as ContactData[];\n contacts = contacts?.filter((contact) => contact.name !== '');\n return contacts;\n }),\n );\n }\n\n contactSelected(contact: ContactData): void {\n this.dialogRef.close(contact);\n }\n\n getNameForContact(contact: CrmObject): string {\n const firstName = this.crmFieldService.getFieldValueFromCrmObject(\n contact,\n StandardExternalIds.FirstName,\n )?.stringValue;\n const lastName = this.crmFieldService.getFieldValueFromCrmObject(\n contact,\n StandardExternalIds.LastName,\n )?.stringValue;\n\n const fullName = [firstName, lastName].filter(Boolean).join(' ').trim();\n\n if (fullName) {\n return fullName;\n }\n return this.crmFieldService.getFieldValueFromCrmObject(contact, StandardExternalIds.Email)?.stringValue || '';\n }\n}\n","

{{ 'EMAIL_BUILDER.CONTEXT_SELECTOR.CONTACT_SELECTOR.TITLE' | translate }}

\n\n
\n
\n \n {{ 'EMAIL_BUILDER.CONTEXT_SELECTOR.CONTACT_SELECTOR.SEARCH' | translate }}\n \n \n
\n
\n @if (contacts$ | async; as contacts) {\n \n @for (c of contacts; track c) {\n \n

{{ c.name }}

\n
\n }\n
\n }\n
\n\n \n\n","import { Component, EventEmitter, Inject, Input, Output } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { TranslateService } from '@ngx-translate/core';\nimport { AccountGroup, ProjectionFilter } from '@vendasta/account-group';\nimport { BusinessSelectorDialogComponent, DialogData } from '@vendasta/businesses';\nimport { Sender, SenderType } from '@vendasta/email';\nimport { BehaviorSubject, Observable, firstValueFrom, map } from 'rxjs';\nimport { switchMap, take } from 'rxjs/operators';\nimport { EmailPreviewHydrationData } from '../../services/preview-rendering.service';\nimport { SENDER_INJECTION_TOKEN } from '../../shared';\nimport { ContactData, ContactSelectorComponent } from './contact-selector-modal/contact-selector.component';\n\nexport interface SelectedPreviewContext {\n accountGroupId: string;\n name: string;\n hasSalesperson: boolean;\n hasSnapshot: boolean;\n contactID?: string;\n useFakeData?: boolean;\n}\n\nexport type Layout = 'vertical' | 'horizontal';\n\n@Component({\n selector: 'email-preview-selector',\n templateUrl: './preview-context-selector.component.html',\n styleUrls: ['./preview-context-selector.component.scss'],\n standalone: false,\n})\nexport class PreviewContextSelectorComponent {\n name: string;\n showWarning$: Observable;\n warningKey$?: string;\n dialogData?: DialogData;\n\n public selectedName: BehaviorSubject = new BehaviorSubject('');\n\n @Input() set hydrationData(v: EmailPreviewHydrationData) {\n const biz = v?.business;\n this.name = biz?.name || 'None selected';\n this.showWarning$ = this.shouldShowWarning(biz);\n this.warningKey$ = biz ? this.getWarningKey(biz) : '';\n this.dialogData = {\n partnerId: v?.partnerID,\n marketId: v?.marketID,\n projectionFilterOverride: {\n napData: true,\n accountGroupExternalIdentifiers: true,\n snapshotReports: true,\n } as ProjectionFilter,\n };\n }\n\n @Input() layout: Layout = 'horizontal';\n\n @Output() contactSelected = new EventEmitter();\n\n @Output() contextSelected = new EventEmitter();\n\n private shouldShowWarning(biz: { hasSnapshot: boolean; hasSalesperson: boolean }): Observable {\n return this.sender$.pipe(\n map((sender) => {\n if (sender.type === SenderType.SENDER_TYPE_PARTNER && biz) {\n return !biz.hasSnapshot || !biz.hasSalesperson;\n } else {\n return false;\n }\n }),\n );\n }\n\n private getWarningKey(biz: {\n accountGroupId: string;\n name: string;\n hasSnapshot: boolean;\n hasSalesperson: boolean;\n }): string {\n if (!biz.hasSalesperson && !biz.hasSnapshot) {\n return 'EMAIL_TEMPLATES.PREVIEW.BUSINESS_SELECTOR.NO_SNAPSHOT_OR_SALESPERSON_WARNING';\n }\n if (!biz.hasSnapshot) {\n return 'EMAIL_TEMPLATES.PREVIEW.BUSINESS_SELECTOR.NO_SNAPSHOT_WARNING';\n }\n if (!biz.hasSalesperson) {\n return 'EMAIL_TEMPLATES.PREVIEW.BUSINESS_SELECTOR.NO_SALESPERSON_WARNING';\n }\n return '';\n }\n\n public contextName$: Observable;\n\n constructor(\n private readonly translate: TranslateService,\n private readonly dialog: MatDialog,\n @Inject(SENDER_INJECTION_TOKEN) private readonly sender$: Observable,\n ) {\n this.contextName$ = this.sender$.pipe(\n switchMap((sender) => {\n if (sender.type === SenderType.SENDER_TYPE_PARTNER) {\n return this.translate.stream('EMAIL_BUILDER.CONTEXT_SELECTOR.BUSINESS');\n } else {\n return this.translate.stream('EMAIL_BUILDER.CONTEXT_SELECTOR.CONTACT');\n }\n }),\n );\n }\n\n async openSelectDialog(): Promise {\n return await firstValueFrom(\n this.sender$.pipe(\n take(1),\n map((sender) => {\n if (sender.type === SenderType.SENDER_TYPE_PARTNER) {\n return this.openBusinessSelectDialog();\n } else {\n return this.openContactSelectDialog();\n }\n }),\n ),\n );\n }\n\n async openContactSelectDialog(): Promise {\n const dialog = this.dialog.open(ContactSelectorComponent, {\n data: this.sender$.pipe(map((sender) => ({ accountGroupID: sender.id }))),\n minWidth: '350px',\n });\n const contact: ContactData = await firstValueFrom(dialog.afterClosed());\n if (contact) {\n const sel: SelectedPreviewContext = {\n accountGroupId: contact.accountGroupID,\n name: contact.name,\n hasSnapshot: false,\n hasSalesperson: false,\n contactID: contact.contactID,\n useFakeData: false,\n };\n this.selectedName.next(contact.name);\n this.contactSelected.emit(contact.contactID);\n this.name = sel.name;\n this.showWarning$ = this.shouldShowWarning(sel);\n this.contextSelected.emit(sel);\n }\n }\n\n async openBusinessSelectDialog(): Promise {\n const dialog = this.dialog.open(BusinessSelectorDialogComponent, {\n data: this.dialogData,\n });\n const ag: AccountGroup = await firstValueFrom(dialog.afterClosed());\n if (ag) {\n const sel: SelectedPreviewContext = {\n accountGroupId: ag.accountGroupId,\n name: ag.napData.companyName,\n hasSnapshot: ag.snapshotReports?.snapshots?.length > 0,\n hasSalesperson: !!ag.accountGroupExternalIdentifiers?.salesPersonId,\n };\n this.selectedName.next(sel.name);\n\n this.name = sel.name;\n this.showWarning$ = this.shouldShowWarning(sel);\n this.contextSelected.emit(sel);\n }\n }\n}\n","
\n {{ 'EMAIL_BUILDER.CONTEXT_SELECTOR.X_FOR_PREVIEW' | translate: { context: (contextName$ | async) } }}\n
\n {{ selectedName | async }}\n @if (showWarning$ | async) {\n warning_filled\n }\n
\n \n
\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { PreviewContextSelectorComponent } from './preview-context-selector.component';\nimport { BusinessSelectorDialogModule } from '@vendasta/businesses';\nimport { GalaxyFormFieldModule } from '@vendasta/galaxy/form-field';\nimport { GalaxyTooltipModule } from '@vendasta/galaxy/tooltip';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { ContactSelectorComponent } from './contact-selector-modal/contact-selector.component';\nimport { MatDialogModule } from '@angular/material/dialog';\nimport { FormsModule } from '@angular/forms';\nimport { InViewportModule } from 'ng-in-viewport';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatListModule } from '@angular/material/list';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { CrmFieldService } from '@galaxy/crm/static';\n\n@NgModule({\n declarations: [PreviewContextSelectorComponent, ContactSelectorComponent],\n providers: [CrmFieldService],\n imports: [\n CommonModule,\n GalaxyFormFieldModule,\n GalaxyTooltipModule,\n MatButtonModule,\n MatIconModule,\n TranslateModule,\n BusinessSelectorDialogModule,\n MatDialogModule,\n FormsModule,\n InViewportModule,\n MatFormFieldModule,\n MatInputModule,\n MatListModule,\n MatProgressSpinnerModule,\n ],\n exports: [PreviewContextSelectorComponent, ContactSelectorComponent],\n})\nexport class PreviewContextSelectorModule {}\n","import { VariableMenuItem } from '../components/dynamic-component-selector';\nimport { InjectionToken } from '@angular/core';\nimport { Footer, TopLogo } from '../components/email-advanced-settings/email-advanced-settings.component';\nimport { Observable } from 'rxjs';\nimport { EmailPreviewHydrationData } from '../services/preview-rendering.service';\n\nexport const DYNAMIC_COMPONENT_DATA_TOKEN: InjectionToken = new InjectionToken(\n 'com.vendasta.email_builder.dynamic_component_data',\n);\nexport const TEMPLATE_HYDRATION_DATA_TOKEN: InjectionToken> = new InjectionToken<\n Observable\n>('com.vendasta.email_builder.hydration_data');\nexport const PLACEHOLDER_LOGO_URL_TOKEN: InjectionToken> = new InjectionToken>(\n 'com.vendasta.email_builder.placeholder_logo_url',\n);\nexport const EMAIL_FOOTER_TOKEN: InjectionToken