const PROPS = {
  TEXT_COLOR: 1,
  BACKGROUND_COLOR: 2,
  FONT_SIZE: 3,
  PADDING: 4,
  MARGIN: 5,
  WIDTH: 6,
  HEIGHT: 7,
  MAX_WIDTH: 8,
  MAX_HEIGHT: 9,
  MIN_WIDTH: 10,
  MIN_HEIGHT: 11,
  IMAGE_URL: 12,
  TOGGLE: 13,
  TEXT_CASE: 14,
  BACKGROUND_PATTERN: 15,
  BORDER: 16,
  BORDER_RADIUS: 17,
};

const elements = {
  logo: {
    id: 'logo',
    title: 'Logo Image',
    cssSelector: 'aside .logo img',
    tooltipAlign: 'top',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.WIDTH, PROPS.MAX_WIDTH, PROPS.HEIGHT, PROPS.MAX_HEIGHT, PROPS.MARGIN, PROPS.PADDING],
    values: {
      [PROPS.MAX_WIDTH]: { value: 150 },
      [PROPS.WIDTH]: { value: 'auto' },
      [PROPS.MAX_HEIGHT]: { value: 150 },
      [PROPS.HEIGHT]: { value: 'auto' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  sidebar: {
    id: 'sidebar',
    props: [PROPS.BACKGROUND_PATTERN],
    title: 'Sibebar',
    tooltipAlign: 'right',
    align: 'top right',
    distance: { x: 10, y: 100 },
    cssSelector: 'aside::before',
    injectableSelector: 'aside',
    values: { [PROPS.BACKGROUND_PATTERN]: { isActive: true, opacity: 80, pattern: '5.svg' } },
  },
  sidebarMenuItem: {
    id: 'sidebarMenuItem',
    title: 'Sidebar Menu Item',
    cssSelector: 'aside .uk-nav-default > li > a',
    tooltipAlign: 'right',
    align: 'top right',
    distance: { x: 40, y: -20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: 'white' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 10, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 5, left: 0, right: 0, bottom: 5, unit: 'px' },
    },
  },
  sidebarMenuItemActive: {
    id: 'sidebarMenuItemActive',
    title: 'Sidebar Menu Item Active',
    cssSelector: 'aside .uk-nav-default > li.uk-active > a',
    tooltipAlign: 'right',
    align: 'top right',
    distance: { x: 40, y: -20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: 'white' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 10, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 5, left: 0, right: 0, bottom: 5, unit: 'px' },
    },
  },
  sidebarSubMenuItem: {
    id: 'sidebarSubMenuItem',
    title: 'Sidebar Sub Menu Item',
    cssSelector: 'aside .uk-nav-default .uk-nav-sub a',
    tooltipAlign: 'right',
    align: 'top right',
    distance: { x: 40, y: -200 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 14, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: 'white' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: -15, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 8, left: 25, right: 0, bottom: 8, unit: 'px' },
    },
  },
  sidebarSubMenuItemActive: {
    id: 'sidebarSubMenuItemActive',
    title: 'Sidebar Sub Menu Item Active',
    cssSelector: 'aside .uk-nav-default .uk-nav-sub .uk-active a',
    tooltipAlign: 'right',
    align: 'top right',
    distance: { x: 40, y: -20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 14, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: 'white' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: -15, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 8, left: 25, right: 0, bottom: 8, unit: 'px' },
    },
  },
  methodNameGet: {
    id: 'methodNameGet',
    title: 'Get Method',
    cssSelector: '.api-method-get',
    tooltipAlign: 'top',
    align: 'top right',
    distance: { x: 50, y: -20 },
    props: [PROPS.FONT_SIZE, PROPS.BORDER_RADIUS, PROPS.PADDING, PROPS.MARGIN, PROPS.BACKGROUND_COLOR, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 10, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.BACKGROUND_COLOR]: { value: '#4CAF50' },
      [PROPS.TEXT_COLOR]: { value: '#FFF' },
      [PROPS.TEXT_CASE]: { value: 'uppercase' },
      [PROPS.BORDER_RADIUS]: { top: 20, left: 20, right: 20, bottom: 20, unit: 'px' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 2, left: 6, right: 6, bottom: 2, unit: 'px' },
    },
  },
  methodNamePost: {
    id: 'methodNamePost',
    title: 'Post Method',
    cssSelector: '.api-method-post',
    tooltipAlign: 'top',
    align: 'top right',
    distance: { x: 50, y: -20 },
    props: [PROPS.FONT_SIZE, PROPS.BORDER_RADIUS, PROPS.PADDING, PROPS.MARGIN, PROPS.BACKGROUND_COLOR, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 10, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.BACKGROUND_COLOR]: { value: '#2196F3' },
      [PROPS.TEXT_COLOR]: { value: '#FFF' },
      [PROPS.TEXT_CASE]: { value: 'uppercase' },
      [PROPS.BORDER_RADIUS]: { top: 20, left: 20, right: 20, bottom: 20, unit: 'px' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 2, left: 6, right: 6, bottom: 2, unit: 'px' },
    },
  },
  methodNamePut: {
    id: 'methodNamePut',
    title: 'Put Method',
    cssSelector: '.api-method-put',
    tooltipAlign: 'top',
    align: 'top right',
    distance: { x: 50, y: -20 },
    props: [PROPS.FONT_SIZE, PROPS.BORDER_RADIUS, PROPS.PADDING, PROPS.MARGIN, PROPS.BACKGROUND_COLOR, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 10, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.BACKGROUND_COLOR]: { value: '#FFC107' },
      [PROPS.TEXT_COLOR]: { value: '#FFF' },
      [PROPS.TEXT_CASE]: { value: 'uppercase' },
      [PROPS.BORDER_RADIUS]: { top: 20, left: 20, right: 20, bottom: 20, unit: 'px' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 2, left: 6, right: 6, bottom: 2, unit: 'px' },
    },
  },
  methodNameDelete: {
    id: 'methodNameDelete',
    title: 'Delete Method',
    cssSelector: '.api-method-delete',
    tooltipAlign: 'top',
    align: 'top right',
    distance: { x: 50, y: -20 },
    props: [PROPS.FONT_SIZE, PROPS.BORDER_RADIUS, PROPS.PADDING, PROPS.MARGIN, PROPS.BACKGROUND_COLOR, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 10, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.BACKGROUND_COLOR]: { value: '#F44336' },
      [PROPS.TEXT_COLOR]: { value: '#FFF' },
      [PROPS.TEXT_CASE]: { value: 'uppercase' },
      [PROPS.BORDER_RADIUS]: { top: 20, left: 20, right: 20, bottom: 20, unit: 'px' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 2, left: 6, right: 6, bottom: 2, unit: 'px' },
    },
  },
  methodNamePatch: {
    id: 'methodNamePatch',
    title: 'Patch Method',
    cssSelector: '.api-method-patch',
    tooltipAlign: 'top',
    align: 'top right',
    distance: { x: 50, y: -20 },
    props: [PROPS.FONT_SIZE, PROPS.BORDER_RADIUS, PROPS.PADDING, PROPS.MARGIN, PROPS.BACKGROUND_COLOR, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 10, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.BACKGROUND_COLOR]: { value: '#FF9800' },
      [PROPS.TEXT_COLOR]: { value: '#FFF' },
      [PROPS.TEXT_CASE]: { value: 'uppercase' },
      [PROPS.BORDER_RADIUS]: { top: 20, left: 20, right: 20, bottom: 20, unit: 'px' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 2, left: 6, right: 6, bottom: 2, unit: 'px' },
    },
  },
  headerMenuItem: {
    id: 'headerMenuItem',
    title: 'Header Menu Item',
    cssSelector: 'header .links a',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#999999' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 40, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  headerSearchInput: {
    id: 'headerSearchInput',
    title: 'Search Box',
    cssSelector: 'header .search input',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.HEIGHT, PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER_RADIUS, PROPS.TEXT_COLOR],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#666' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 6, right: 40, bottom: 0, unit: 'px' },
      [PROPS.HEIGHT]: { value: 40 },
      [PROPS.BORDER_RADIUS]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  headerSearchResultBox: {
    id: 'headerSearchResultBox',
    title: 'Search Result Container',
    distance: { y: 20 },
    cssSelector: 'header .search-result a',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    props: [PROPS.BACKGROUND_COLOR, PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER_RADIUS],
    values: {
      [PROPS.BACKGROUND_COLOR]: { value: '#f8f8f8' },
      [PROPS.MARGIN]: { top: 5, left: 0, right: 0, bottom: 5, unit: 'px' },
      [PROPS.PADDING]: { top: 4, left: 8, right: 8, bottom: 4, unit: 'px' },
      [PROPS.BORDER_RADIUS]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  headerSearchResultHeader: {
    id: 'headerSearchResultHeader',
    title: 'Search Result Title',
    cssSelector: '.search-result a > strong',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#333' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  headerSearchResultPath: {
    id: 'headerSearchResultPath',
    title: 'Search Result Path',
    cssSelector: '.search-result a > span',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#333' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  projectName: {
    id: 'projectName',
    title: 'Project Name',
    cssSelector: 'main > #project-name',
    tooltipAlign: 'right',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 42, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  projectDetails: {
    id: 'projectDetails',
    title: 'Project Description',
    cssSelector: 'main > .project-details',
    tooltipAlign: 'right',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 18, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#2d3c41' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 20, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  projectType: {
    id: 'projectType',
    title: 'Source Type',
    cssSelector: '.encoding-type-name',
    tooltipAlign: 'right',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER, PROPS.BORDER_RADIUS, PROPS.TEXT_COLOR, PROPS.BACKGROUND_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 10, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: 'white' },
      [PROPS.TEXT_CASE]: { value: 'capitalize' },
      [PROPS.BORDER_RADIUS]: { top: 15, left: 15, right: 15, bottom: 15, unit: 'px' },
      [PROPS.MARGIN]: { top: 20, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 3, left: 7, right: 7, bottom: 3, unit: 'px' },
      [PROPS.BORDER]: { top: 1, right: 1, bottom: 1, left: 1, unit: 'px', type: 'solid', color: window.color.base },
      [PROPS.BACKGROUND_COLOR]: { value: window.color.base, hint: 'This is the base color, which will be converted to the color you provide in the main api-html form while generating HTML from your api-spec. If you change this color then the changed color will be used instead of base color.' },
    },
  },
  projectSource: {
    id: 'projectSource',
    title: 'Source Url',
    cssSelector: '.encoding-type-file',
    tooltipAlign: 'right',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.TEXT_COLOR, PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER, PROPS.BORDER_RADIUS, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 10, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_CASE]: { value: 'capitalize' },
      [PROPS.BORDER_RADIUS]: { top: 15, left: 15, right: 15, bottom: 15, unit: 'px' },
      [PROPS.MARGIN]: { top: 20, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 3, left: 7, right: 7, bottom: 3, unit: 'px' },
      [PROPS.BORDER]: { top: 1, right: 1, bottom: 1, left: 1, unit: 'px', type: 'solid', color: '#fca130' },
      [PROPS.TEXT_COLOR]: { value: '#fca130' },
    },
  },
  tagTitle: {
    id: 'tagTitle',
    title: 'Tag Title',
    cssSelector: 'main > h2',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 5 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 32, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 40, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathTitle: {
    id: 'pathTitle',
    title: 'Path Title',
    cssSelector: '.path > h3',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 5 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 24, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathDetails: {
    id: 'pathDetails',
    title: 'Path Description',
    cssSelector: '.path > p',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 5 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#666' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 20, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathUrlBox: {
    id: 'pathUrlBox',
    title: 'Url Box',
    distance: { y: 5 },
    cssSelector: '.path .path-url',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    props: [PROPS.BACKGROUND_COLOR, PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER_RADIUS],
    values: {
      [PROPS.BACKGROUND_COLOR]: { value: '#f8f8f8' },
      [PROPS.MARGIN]: { top: 30, left: 0, right: 0, bottom: 30, unit: 'px' },
      [PROPS.PADDING]: { top: 10, left: 15, right: 15, bottom: 10, unit: 'px' },
      [PROPS.BORDER_RADIUS]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathUrlMethod: {
    id: 'pathUrlMethod',
    title: 'Path Method',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 20 },
    cssSelector: '.path .path-url .api-method',
    props: [PROPS.FONT_SIZE, PROPS.BORDER_RADIUS, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 11, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: 'white' },
      [PROPS.TEXT_CASE]: { value: 'uppercase' },
      [PROPS.BORDER_RADIUS]: { top: 20, left: 20, right: 20, bottom: 20, unit: 'px' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 2, left: 6, right: 6, bottom: 2, unit: 'px' },
    },
  },
  pathUrlRoot: {
    id: 'pathUrlRoot',
    title: 'Path Root Url',
    cssSelector: '.path .path-url .root',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#666' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 10, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathUrlPath: {
    id: 'pathUrlPath',
    title: 'Url Path',
    cssSelector: '.path .path-url .link',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#10b3d6' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: -2, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathUrlTry: {
    id: 'pathUrlTry',
    title: 'Tryout Button',
    cssSelector: '.path .path-url > a',
    tooltipAlign: 'bottom',
    align: 'bottom left',
    distance: { y: 15, x: 60 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: window.color.base, hint: 'This is the base color, which will be converted to the color you provide in the main api-html form while generating HTML from your api-spec. If you change this color then the changed color will be used instead of base color.' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathTab: {
    id: 'pathTab',
    title: 'Tab not active',
    cssSelector: 'ul[uk-tab] li > a',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 5 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 14, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#999' },
      [PROPS.TEXT_CASE]: { value: 'uppercase' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 2, unit: 'px' },
      [PROPS.PADDING]: { top: 5, left: 10, right: 10, bottom: 5, unit: 'px' },
    },
  },
  pathTabActive: {
    id: 'pathTabActive',
    title: 'Tab Active',
    cssSelector: 'ul[uk-tab] li.uk-active > a',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 5 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.BORDER, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 14, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#333' },
      [PROPS.TEXT_CASE]: { value: 'uppercase' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 2, unit: 'px' },
      [PROPS.PADDING]: { top: 5, left: 10, right: 10, bottom: 5, unit: 'px' },
      [PROPS.BORDER]: { bottom: 2, color: window.color.base },
    },
  },
  pathRequestContainer: {
    id: 'pathRequestContainer',
    title: 'Request Container',
    distance: { y: 5 },
    cssSelector: '.path .path-tab',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    props: [PROPS.BACKGROUND_COLOR, PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER_RADIUS],
    values: {
      [PROPS.BACKGROUND_COLOR]: { value: '#f8f8f8' },
      [PROPS.MARGIN]: { top: -20, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 15, left: 20, right: 20, bottom: 15, unit: 'px' },
      [PROPS.BORDER_RADIUS]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestHeader: {
    id: 'pathRequestHeader',
    title: 'Request Title',
    cssSelector: '.path-tab-request > p',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#666' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestBlock: {
    id: 'pathRequestBlock',
    title: 'Request Block',
    distance: { y: 5 },
    cssSelector: '.path-tab-request .blocks-block',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    props: [PROPS.BACKGROUND_COLOR, PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER_RADIUS],
    values: {
      [PROPS.BACKGROUND_COLOR]: { value: '#f8f8f8' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 10, left: 10, right: 10, bottom: 10, unit: 'px' },
      [PROPS.BORDER_RADIUS]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestParamName: {
    id: 'pathRequestParamName',
    title: 'Request Param Name',
    cssSelector: '.path-tab-request .blocks-block-info-col > span:not(.attr)',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#666666' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestParamOptional: {
    id: 'pathRequestParamOptional',
    title: 'Request Param Optional',
    cssSelector: '.path-tab-request .blocks-block-info-col > .uk-text-meta',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 14, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#999' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestParamRequired: {
    id: 'pathRequestParamRequired',
    title: 'Request Param Required',
    cssSelector: '.path-tab-request .blocks-block-info-col > .red',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 14, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#f44336' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestParamDatatype: {
    id: 'pathRequestParamDatatype',
    title: 'Request Param Datatype',
    cssSelector: '.path .keyword',
    tooltipAlign: 'bottom',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#7ec699' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestParamDesc: {
    id: 'pathRequestParamDesc',
    title: 'Request Param Description',
    cssSelector: '.path .blocks .blocks-block .blocks-block-desc-col .details',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#847d7d' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestParamDefault: {
    id: 'pathRequestParamDefault',
    title: 'Request Param Default',
    cssSelector: '.path .blocks .blocks-block .blocks-block-desc-col .default',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#666' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathRequestParamDefaultValue: {
    id: 'pathRequestParamDefaultValue',
    title: 'Request Param Default Value',
    cssSelector: '.path .blocks .blocks-block .blocks-block-desc-col .default-value',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#847d7d' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathResponseHeader: {
    id: 'pathResponseHeader',
    title: 'Response Header',
    cssSelector: '.path-tab-response > h4',
    tooltipAlign: 'right',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 20, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: 'black' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathResponseDesc: {
    id: 'pathResponseDesc',
    title: 'Response Description',
    cssSelector: '.path-tab-response .blocks .blocks-block .blocks-block-desc-col .details',
    tooltipAlign: 'top',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#847d7d' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathResponseBlock: {
    id: 'pathResponseBlock',
    title: 'Request Code Container',
    distance: { y: 10 },
    cssSelector: '.path .path-tab-response .blocks .blocks-block .blocks-block-desc-col',
    tooltipAlign: 'top',
    align: 'bottom center',
    props: [PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER_RADIUS],
    values: {
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 5, right: 5, bottom: 0, unit: 'px' },
      [PROPS.BORDER_RADIUS]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  pathResponseCodeBox: {
    id: 'pathResponseCodeBox',
    title: 'Codebox ',
    distance: { y: 20 },
    cssSelector: '.path pre > code',
    tooltipAlign: 'top',
    align: 'bottom center',
    props: [PROPS.BACKGROUND_COLOR, PROPS.PADDING, PROPS.MARGIN, PROPS.BORDER_RADIUS],
    values: {
      [PROPS.BACKGROUND_COLOR]: { value: '#011627' },
      [PROPS.MARGIN]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
      [PROPS.PADDING]: { top: 15, left: 20, right: 20, bottom: 15, unit: 'px' },
      [PROPS.BORDER_RADIUS]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  authTitle: {
    id: 'authTitle',
    title: 'Auth Title',
    cssSelector: 'main > .auth > h3',
    tooltipAlign: 'left',
    align: 'bottom center',
    distance: { y: 20 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.MARGIN, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 24, isBold: true, isItalic: false, isUnderline: false },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 40, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
  authDesc: {
    id: 'authDesc',
    title: 'Auth Description',
    cssSelector: 'main > .auth > p',
    tooltipAlign: 'top',
    align: 'bottom center',
    distance: { y: 10 },
    props: [PROPS.FONT_SIZE, PROPS.PADDING, PROPS.TEXT_COLOR, PROPS.TEXT_CASE],
    values: {
      [PROPS.FONT_SIZE]: { value: 16, isBold: false, isItalic: false, isUnderline: false },
      [PROPS.TEXT_COLOR]: { value: '#666666' },
      [PROPS.TEXT_CASE]: { value: 'none' },
      [PROPS.MARGIN]: { top: 20, left: 0, right: 0, bottom: 20, unit: 'px' },
      [PROPS.PADDING]: { top: 0, left: 0, right: 0, bottom: 0, unit: 'px' },
    },
  },
};

const editableElemets = [
  { selector: '.project-details' },
  { selector: 'h1 a' },
  { selector: 'h2 a' },
  { selector: 'h3 a' },
  { selector: '.encoding-type-name' },
  { selector: '.encoding-type-file' },
  { selector: '.auth > h3' },
  { selector: '.auth > h5' },
  { selector: '.auth > p' },
  { selector: '.auth td' },
  { selector: '.path .path-url .root', applyUnique: false },
  { selector: '.path .path-url .link' },
  { selector: '.path .path-url a', applyUnique: false },
  { selector: '.path .path-tab-response h4' },
  { selector: '.path .path-tabs a[data-tab="request"]', applyUnique: false },
  { selector: '.path .path-tabs a[data-tab="response"]', applyUnique: false },
  { selector: '.path .path-tabs a[data-tab="coding"]', applyUnique: false },
  { selector: 'aside ul li a' },
  { selector: '.path p' },
  { selector: '.path .blocks .blocks-block .blocks-block-info-col span' },
  { selector: '.path .blocks .blocks-block .blocks-block-desc-col span' },
  { selector: '.request-box-details .btn-model-example', applyUnique: false },
  { selector: '.request-box-details .btn-model-definition', applyUnique: false },
  { selector: '.path .code-tabs a[data-tab="curl"]', applyUnique: false },
  { selector: '.path .code-tabs a[data-tab="javascript"]', applyUnique: false },
  { selector: '.path .code-tabs a[data-tab="node"]', applyUnique: false },
  { selector: '.path .code-tabs a[data-tab="python"]', applyUnique: false },
];



class Editor {
  constructor() {
    this.selectedId = null;
    this.appliedProps = {};
    this.history = {};
    this.textChangeHistory = {};
    this.assetsRoot = 'https://cdn.jsdelivr.net/npm/api-html@1.1.2/themes/compact';

    this.injectEditorElements();
    this.attachEvents();
    this.attachPopup();
    this.loadLibraries();
  }

  /**
   * Inject the selectable class and unique Id for each editable element based on the cssSelector
   * Attach the tooltip to all the selectable elements
  */
  injectEditorElements() {
    const elemenetsArr = Object.keys(elements).map(e => elements[e]);
    elemenetsArr.forEach(({ id = '', cssSelector = '', injectableSelector = '', tooltipAlign = 'top', title = 'Click to Edit' }) => {
      $(injectableSelector || cssSelector)
        .addClass('zama-select')
        .attr('data-zama-id', id)
        .attr('uk-tooltip', `title:${title}; pos: ${tooltipAlign}`)
    });

    editableElemets.forEach(({ selector = '', applyUnique = true }) => {
      $(selector).attr('contenteditable', true);

      if (!applyUnique) {
        $(selector).attr('data-my-selector', selector);
      }
    });

    $('body').append(`
      <div class="global-settings">
        <div class="settings-button">
          <span uk-icon="icon: cog; ratio: 2;"></span>
        </div>
        <div class="settings-body" style="display: none;">
          <!--p>All the changes has been added to the main page. Please close this window and preview or download the result.</p-->
          <button class="uk-button uk-button-primary uk-width-1-1 setting-download">Download</button>
          <hr class="uk-divider-icon" />
          <button class="uk-button uk-button-default uk-width-1-1 setting-preview">Preview</button>
        </div>
      </div>
    `);
  }

  generateBackgroundPatterns({ title, value, id }) {
    const { isActive = true, opacity = 0, pattern, url: patternUrl = '' } = value;
    const images = ['1.jpg', '2.jpg', '3.jpg', '4.svg', '5.svg', '6.svg', '7.svg', '8.svg', '9.svg', '10.svg'];
    const getUrl = (img) => `${this.assetsRoot}/assets/img/patterns/${img}`;

    return `
      <div style="margin-bottom: 20px">
        <label>Show Pattern <input ${isActive ? 'checked' : ''} class="uk-checkbox background-pattern-active" style="margin-left: 10px" type="checkbox"></label>
        <p>Opacity</p>
        <span>0%</span>
        <input type="range" value="${opacity}" min="0" max="100" class="background-pattern-opacity" style="width: calc(100% - 80px)" />
        <span>100%</span>
        <p>Patterns</p>
        <div class="uk-margin background-pattern" id="${id}">
          ${images.map(e => `
            <div
              class="background-pattern-block ${e === pattern ? 'background-pattern-block-selected' : ''}"
              data-value="${e}"
              style="
                background-image: linear-gradient(to bottom, #888, rgba(0, 0, 0, 0.4)), url(${getUrl(e)});
              "
            ></div>
          `).join('')}
        </div>
        <p>Or</p>
        <input class="uk-input background-pattern-url" type="text" value="${patternUrl}" placeholder="Enter pattern url">
        <p style="font-size: 10px; margin-top: 5px;">Keep it empty, if you want to use the above patterns</p>
      </div>
    `;
  }

  generateUnits() {
    return `
      <div class="zama-chips" style="display: none;">
        <a href="#">px</a>
        <a href="#">%</a>
        <a href="#">em</a>
        <a href="#">rem</a>
        <a href="#">cm</a>
        <a href="#">in</a>
        <a href="#">mm</a>
        <a href="#">pt</a>
        <a href="#">vh</a>
        <a href="#">vw</a>
      </div>
    `;
  }

  generateTextField({ title, value: _value = {}, id, isUnit = true }) {
    const { value = 0, unit = 'px', hint = '' } = _value || {};
    return `
      <div class="uk-margin zama-units">
        <label class="uk-form-label">
          ${title}
          ${hint ? `
            <span uk-icon="info" style="float: right;"></span>
            <div uk-dropdown="mode: click; pos: bottom-right" style="max-width: 150px">${hint}</div>    
          ` : ''}
        </label>
        <div class="uk-inline"${id ? ` id="${id}"` : ''}>
          ${ isUnit ? `<a class="uk-form-icon uk-form-icon-flip zama-unit" href="#" uk-icon="icon: chevron-down"><span class="value">${unit}</span></a>` : '' }
          <input class="uk-input" type="text" value="${value}" placeholder="Enter ${title}">
        </div>
        ${this.generateUnits()}
      </div>
    `;
  }

  generateSelectField({ title, value: _value = {}, id }) {
    const { value: selectedValue = '', options = [], hint = '' } = _value || {};
    return `
      <div class="uk-margin"${id ? ` id="${id}"` : ''}>
        <label class="uk-form-label">
          ${title}
          ${hint ? `
            <span uk-icon="info" style="float: right;"></span>
            <div uk-dropdown="mode: click; pos: bottom-right" style="max-width: 150px">${hint}</div>    
          ` : ''}
        </label>
        <select class="uk-select">
          ${options.map(([value, label]) => `<option value="${value}"${value === selectedValue ? ' selected' : ''}>${label || value}</option>`).join('')}
        </select>
      </div>
    `;
  }

  generateFontField({ title, value: _value = {}, id }) {
    const { value = '', unit = 'px', isBold = false, isItalic = false, isUnderline = false, hint = '' } = _value || {};
    return `
        <div class="uk-margin zama-units"${id ? ` id="${id}"` : ''}>
          <label class="uk-form-label">
            ${title}
            ${hint ? `
              <span uk-icon="info" style="float: right;"></span>
              <div uk-dropdown="mode: click; pos: bottom-right" style="max-width: 150px">${hint}</div>    
            ` : ''}
          </label>

          <div class="uk-inline">
            <a class="uk-form-icon uk-form-icon-flip zama-unit" href="#" uk-icon="icon: chevron-down"><span class="value">${unit}</span></a>
            <input class="uk-input" type="number" value="${value}" placeholder="Enter ${title}">
          </div>
          <div style="font-size: 10px; margin-top: 10px;">
            <label><input ${isBold ? 'checked' : ''} class="uk-checkbox is-bold" style="margin-left: 10px" type="checkbox"> Bold</label>
            <label><input ${isItalic ? 'checked' : ''} class="uk-checkbox is-italic" style="margin-left: 10px" type="checkbox"> Italic</label>
            <label><input ${isUnderline ? 'checked' : ''} class="uk-checkbox is-underline" style="margin-left: 10px" type="checkbox"> Underline</label>
          </div>
          ${this.generateUnits()}
        </div>
    `;
  }

  generatePaddingField({ title, value = {}, id }) {
    const { top = 0, left = 0, right = 0, bottom = 0, unit = 'px', hint = '' } = value;

    return `
      <div class="uk-margin field zama-units" id="${id}">
        <label class="uk-form-label">
          ${title}
          ${hint ? `
            <span uk-icon="info" style="float: right;"></span>
            <div uk-dropdown="mode: click; pos: bottom-right" style="max-width: 150px">${hint}</div>    
          ` : ''}
        </label>
        <div class="field-padding">
          Unit: <a class="zama-unit" href="#" uk-icon="icon: chevron-down" style="float: right"><span class="value">px</span></a>
          <span uk-icon="icon: plus; ratio: 3" style="color: #d4d3d3"></span>
          <input class="field-padding-top" type="number" value="${top}"/>
          <input class="field-padding-left" type="number" value="${left}"/>
          <input class="field-padding-right" type="number" value="${right}"/>
          <input class="field-padding-bottom" type="number" value="${bottom}"/>
        </div>
        ${this.generateUnits()}
      </div>
    `;
  }

  generateBorderField({ title, value = {}, id }) {
    const { top = 0, left = 0, right = 0, bottom = 0, unit = 'px', color = window.color.base, type = 'solid', hint = '' } = value;

    return `
      <div class="uk-margin field zama-units" id="${id}">
        <label class="uk-form-label">
          ${title}
          ${hint ? `
            <span uk-icon="info" style="float: right;"></span>
            <div uk-dropdown="mode: click; pos: bottom-right" style="max-width: 150px">${hint}</div>    
          ` : ''}
        </label>
        <div class="field-padding field-border">
          Unit: <a class="zama-unit" href="#" uk-icon="icon: chevron-down" style="float: right"><span class="value">px</span></a>
          ${this.generateSelectField({ title: 'Type', value: { value: type, options: [['solid', 'Solid'], ['dotted', 'Dotted'], ['dashed', 'Dashed'], ['double', 'Double']] } })}
          ${this.generateColorField({ title: 'Color', value: { value: color } })}
          <span uk-icon="icon: plus; ratio: 3" style="color: #d4d3d3"></span>
          <input class="field-padding-top" type="number" value="${top}"/>
          <input class="field-padding-left" type="number" value="${left}"/>
          <input class="field-padding-right" type="number" value="${right}"/>
          <input class="field-padding-bottom" type="number" value="${bottom}"/>
        </div>
        ${this.generateUnits()}
      </div>
    `;
  }

  generateColorField({ title, value: _value = '', id }) {
    const { value = '', hint = '' } = _value;
    return `
      <div class="uk-margin"${id ? ` id="${id}"` : ''}>
        <label class="uk-form-label">
          ${title}
          ${hint ? `
            <span uk-icon="info" style="float: right;"></span>
            <div uk-dropdown="mode: click; pos: bottom-right" style="max-width: 150px">${hint}</div>    
          ` : ''}
        </label>
        <div class="uk-form-controls">
          <input class="uk-input color-picker" value="${value}" placeholder="Enter ${title}">
        </div>
      </div>
    `
  }

  getFieldValue(type) {
    if (type === PROPS.PADDING || type === PROPS.MARGIN || type === PROPS.BORDER_RADIUS) {
      const top = $(`#field-id-${type} .field-padding-top`).val()
      const left = $(`#field-id-${type} .field-padding-left`).val()
      const right = $(`#field-id-${type} .field-padding-right`).val()
      const bottom = $(`#field-id-${type} .field-padding-bottom`).val()
      const unit = $(`#field-id-${type} .zama-unit .value`).text()
      return { top, left, right, bottom, unit };
    } else if (type === PROPS.BACKGROUND_PATTERN) {
      const pattern = $('.background-pattern-block-selected').attr('data-value');
      const opacity = $('.background-pattern-opacity').val();
      const url = $('.background-pattern-url').val();
      const isActive = $('.background-pattern-active')[0].checked;

      return { isActive, opacity, pattern, url };
    } else if (type === PROPS.BORDER) {
      const top = $(`#field-id-${type} .field-padding-top`).val()
      const left = $(`#field-id-${type} .field-padding-left`).val()
      const right = $(`#field-id-${type} .field-padding-right`).val()
      const bottom = $(`#field-id-${type} .field-padding-bottom`).val()
      const unit = $(`#field-id-${type} .zama-unit .value`).text();
      const color = $(`#field-id-${type} input.color-picker`).val();
      const borderType = $(`#field-id-${type} select`).val();

      return { top, left, right, bottom, color, type: borderType, unit };
    } else if (type === PROPS.TEXT_CASE) {
      const value = $(`#field-id-${type} select`).val()
      return { value };
    } else if (type === PROPS.FONT_SIZE) {
      const value = $(`#field-id-${type} input`).val();
      const isBold = $(`#field-id-${type} .is-bold`)[0].checked;
      const isItalic = $(`#field-id-${type} .is-italic`)[0].checked;
      const isUnderline = $(`#field-id-${type} .is-underline`)[0].checked;
      return { value, isBold, isItalic, isUnderline };
    } else {
      const value = $(`#field-id-${type} input`).val()
      const unit = $(`#field-id-${type} .zama-unit .value`).text()
      return { value, unit };
    }
  }

  generateFields({ props, values = {} }) {
    let onCompleteStack = [];

    let html = props.map(e => {
      let html = '';

      if (e === PROPS.PADDING) {
        html = this.generatePaddingField({
          id: `field-id-${PROPS.PADDING}`,
          title: 'Padding',
          value: values[PROPS.PADDING],
        });
      } else if (e === PROPS.MARGIN) {
        html = this.generatePaddingField({
          id: `field-id-${PROPS.MARGIN}`,
          title: 'Margin',
          value: values[PROPS.MARGIN],
        });
      } else if (e === PROPS.BORDER_RADIUS) {
        html = this.generatePaddingField({
          id: `field-id-${PROPS.BORDER_RADIUS}`,
          title: 'Border Rounds',
          value: values[PROPS.BORDER_RADIUS],
        });
      } else if (e === PROPS.BORDER) {
        html = this.generateBorderField({
          id: `field-id-${PROPS.BORDER}`,
          title: 'Border',
          value: values[PROPS.BORDER],
        });

        onCompleteStack.push(() => {
          $('.color-picker').spectrum({
            type: "component",
            showPalette: false,
          });
        })
      } else if (e === PROPS.IMAGE_URL) {
        html = this.generateTextField({
          id: `field-id-${PROPS.IMAGE_URL}`,
          title: 'Image URL',
          value: values[PROPS.IMAGE_URL],
          isUnit: false,
        });
      } else if (e === PROPS.WIDTH) {
        html = this.generateTextField({
          id: `field-id-${PROPS.WIDTH}`,
          title: 'Width',
          value: values[PROPS.WIDTH],
        });
      } else if (e === PROPS.MAX_WIDTH) {
        html = this.generateTextField({
          id: `field-id-${PROPS.MAX_WIDTH}`,
          title: 'Maximum Width',
          value: values[PROPS.MAX_WIDTH],
        });
      } else if (e === PROPS.MIN_WIDTH) {
        html = this.generateTextField({
          id: `field-id-${PROPS.MIN_WIDTH}`,
          title: 'Minimum Width',
          value: values[PROPS.MIN_WIDTH],
        });
      } else if (e === PROPS.HEIGHT) {
        html = this.generateTextField({
          id: `field-id-${PROPS.HEIGHT}`,
          title: 'Height',
          value: values[PROPS.HEIGHT],
        });
      } else if (e === PROPS.MAX_HEIGHT) {
        html = this.generateTextField({
          id: `field-id-${PROPS.MAX_HEIGHT}`,
          title: 'Maximum Height',
          value: values[PROPS.MAX_HEIGHT],
        });
      } else if (e === PROPS.MIN_HEIGHT) {
        html = this.generateTextField({
          id: `field-id-${PROPS.MIN_HEIGHT}`,
          title: 'Minimum Height',
          value: values[PROPS.MIN_HEIGHT],
        });
      } else if (e === PROPS.FONT_SIZE) {
        html = this.generateFontField({
          id: `field-id-${PROPS.FONT_SIZE}`,
          title: 'Font Size',
          value: values[PROPS.FONT_SIZE],
        });
      } else if (e === PROPS.TEXT_COLOR) {
        html = this.generateColorField({
          id: `field-id-${PROPS.TEXT_COLOR}`,
          title: 'Text Color',
          value: values[PROPS.TEXT_COLOR]
        });

        onCompleteStack.push(() => {
          $('.color-picker').spectrum({
            type: "component",
            showPalette: false,
          });
        })
      } else if (e === PROPS.BACKGROUND_COLOR) {
        html = this.generateColorField({
          id: `field-id-${PROPS.BACKGROUND_COLOR}`,
          title: 'Background Color',
          value: values[PROPS.BACKGROUND_COLOR]
        });

        onCompleteStack.push(() => {
          $('.color-picker').spectrum({
            type: "component",
            showPalette: false,
          });
        })
      } else if (e === PROPS.BACKGROUND_PATTERN) {
        html = this.generateBackgroundPatterns({
          id: `field-id-${PROPS.BACKGROUND_PATTERN}`,
          title: 'Background Patterns',
          value: values[PROPS.BACKGROUND_PATTERN],
        });

        onCompleteStack.push(() => {
          $('.background-pattern-block').off('click');
          $('.background-pattern-block').click(function() {
            $('.background-pattern-block-selected').removeClass('background-pattern-block-selected');
            $(this).addClass('background-pattern-block-selected');
            $('.background-pattern').trigger('change');
          });
        });
      } else if (e === PROPS.TEXT_CASE) {
        html = this.generateSelectField({
          id: `field-id-${PROPS.TEXT_CASE}`,
          title: 'Transform Text Case',
          value: {
            value: values[PROPS.TEXT_CASE].value,
            options: [
              ['none', 'Normal'],
              ['uppercase', 'Upper Case'],
              ['capitalize', 'Capitalize'],
              ['lowercase', 'Lower Case']
            ],
          },
        });
      }

      return html;
    }).join('');

    onCompleteStack.push(() => {
      $('.zama-unit').off('click');
      $('.zama-unit').click(function() {
        $(this).parents('.zama-units').find('.zama-chips').toggle();
      });

      $('.zama-chips a').click(function() {
        $(this).parents('.zama-units').find('.zama-unit .value').text($(this).text());
        $(this).parents('.zama-units').find('.zama-chips').hide();
        $('.zama-unit').first().trigger('change');
      });
    });

    return { onCompleteStack, html };
  }

  generatePopup({ title, items }) {
    return `
      ${title ? `<h4>${title}</h4>` : ''}
      <form class="uk-form-stacked" onsubmit="e => e.preventDefault()">
        ${items}
        <div style="float: right">
          <button class="uk-button uk-button-small uk-button-default button-reset" type="button">Reset</button>
          <button class="uk-button uk-button-small uk-button-primary button-apply" type="button">Apply</button>
        </div>
      </form>
    `;
  }

  createPopup() {
    // Get the properties of the selected element
    const { id = '', props = [], title = '', values = {} } = this.getData();
    
    // Generate all the fields for the currently selected element
    const { html, onCompleteStack } = this.generateFields({ id, props, values });

    // Generate html for popup modal
    const popupHTML = this.generatePopup({ title, items: html });
    
    // Add the generated html next to the selected element
    this.setPopup(popupHTML);

    // Show the popup modal
    this.showPopup();

    // Attach a handler which will be triggered on apply click
    $('.zama-popup .button-apply').off('click');

    // Apply style on change of all the inputs inside the form
    $('.zama-popup input, .zama-popup .zama-unit, .background-pattern, .zama-popup select').change(() => this.applyStyle());

    // Apply style on clicking the apply button
    $('.zama-popup .button-apply').click(() => {
      this.applyStyle();
      this.hidePopup();
      // Deselect the pre-selected element
      $('.zama-selected').removeClass('zama-selected');
    });

    // Attach handler for reseting to the default values
    $('.zama-popup .button-reset').off('click');
    $('.zama-popup .button-reset').click(() => this.resetDefaultValues());

    // Attach the close handler
    $('.zama-popup .button-close').off('click');
    $('.zama-popup .button-close').click(() => {
      this.hidePopup();
      // Deselect the pre-selected element
      $('.zama-selected').removeClass('zama-selected');
    });

    // Execute the stacked functions after the dom generation
    onCompleteStack.forEach((e) => e());
  }

  /**
   * Reset the form to the default values
  */
  resetDefaultValues() {
    const { id } = this.getData();

    // Remove already existing style element, to not override with the newly applying style.
    $(`style#${id}`).remove();
    
    // Remove the values object from history object
    delete this.history[id];
    
    // Recreate the popup to get the default values
    this.createPopup();
  }

  /**
   * Generate css rules for the effected style changes
  */
  generateCssRules({ values, cssSelector }) {
    return values.map(({ type, values }) => {
      if (type === PROPS.MAX_WIDTH) {
        const { value = 0, unit = 'px' } = values;
        return `max-width: ${value}${unit} !important`;
      } else if (type === PROPS.MIN_WIDTH) {
        const { value = 0, unit = 'px' } = values;
        return `min-width: ${value}${unit} !important`;
      } else if (type === PROPS.WIDTH) {
        const { value = 0, unit = 'px' } = values;
        return `width: ${value}${unit} !important`;
      } else if (type === PROPS.MIN_HEIGHT) {
        const { value = 0, unit = 'px' } = values;
        return `min-height: ${value}${unit} !important`;
      } else if (type === PROPS.HEIGHT) {
        const { value = 0, unit = 'px' } = values;
        return `height: ${value}${unit} !important`;
      } else if (type === PROPS.MAX_HEIGHT) {
        const { value = 0, unit = 'px' } = values;
        return `max-height: ${value}${unit} !important`;
      } else if (type === PROPS.PADDING) {
        const { top = 0, left = 0, right = 0, bottom = 0, unit = 'px' } = values;
        return `padding: ${top}${unit} ${right}${unit} ${bottom}${unit} ${left}${unit} !important`;
      } else if (type === PROPS.MARGIN) {
        const { top = 0, left = 0, right = 0, bottom = 0, unit = 'px' } = values;
        return `margin: ${top}${unit} ${right}${unit} ${bottom}${unit} ${left}${unit} !important`;
      } else if (type === PROPS.BORDER_RADIUS) {
        const { top = 0, left = 0, right = 0, bottom = 0, unit = 'px' } = values;
        return `border-radius: ${top}${unit} ${right}${unit} ${bottom}${unit} ${left}${unit} !important`;
      } else if (type === PROPS.BORDER) {
        const { top = 0, left = 0, right = 0, bottom = 0, unit = 'px', color = '', type: borderType = 'solid' } = values;
        const border = [
          `border-top: ${top}${unit} ${borderType} ${color} !important`,
          `border-right: ${right}${unit} ${borderType} ${color} !important`,
          `border-bottom: ${bottom}${unit} ${borderType} ${color} !important`,
          `border-left: ${left}${unit} ${borderType} ${color} !important`,
        ];
        return border.join(';');
      } else if (type === PROPS.IMAGE_URL) {
        const { value } = values;

        if (value) {
          $(cssSelector).attr('src', value);
        }

        return;
      }  else if (type === PROPS.TEXT_CASE) {
        const { value } = values;
        return `text-transform: ${value} !important`;
      } else if (type === PROPS.TEXT_COLOR) {
        const { value } = values;
        return `color: ${value} !important`;
      } else if (type === PROPS.BACKGROUND_COLOR) {
        const { value } = values;
        return `background-color: ${value} !important`;
      } else if (type === PROPS.FONT_SIZE) {
        const { value = 14, unit = 'px', isBold, isItalic, isUnderline } = values;
        const css = [`font-size: ${value}${unit} !important`];
        
        if (isBold) {
          css.push(`font-weight: 500 !important`);
        } else {
          css.push(`font-weight: normal !important`);
        }

        if (isItalic) {
          css.push(`font-style: italic !important`);
        } else {
          css.push(`font-style: normal !important`);
        }

        if (isUnderline) {
          css.push(`text-decoration: underline !important`);
        } else {
          css.push(`text-decoration: none !important`);
        }

        return css.join(';');
      } else if (type === PROPS.BACKGROUND_PATTERN) {
        const { isActive, opacity, pattern, url } = values;
        let cssRule = `background-image: linear-gradient(to bottom, #888, rgba(0, 0, 0, ${parseInt(opacity) / 100})), url(${this.assetsRoot}/assets/img/patterns/${pattern})`
        
        if (url) {
          cssRule = `background-image: linear-gradient(to bottom, #888, rgba(0, 0, 0, ${parseInt(opacity) / 100})), url(${url})`
        }

        if (!isActive) {
          cssRule = 'background-image: none !important'
        }

        return cssRule;
      }

      return '';
    }).join('; ');
  }

  /**
   * A handler function which will be exectuted once apply has been clicked
  */
  applyStyle() {
    const { id, props = [], cssSelector } = this.getData();
    const values = props.map(e => ({type: e, values: this.getFieldValue(e)}));
    let cssRules = this.generateCssRules({ values, cssSelector });
    cssRules = `${cssSelector} { ${cssRules} }`;

    // Remove already existing style element, to not override with the newly applying style.
    $(`style#${id}`).remove();

    // Create style element and add css rules for the selected element
    const style = document.createElement('style')            
    style.id = id;
    style.innerText = cssRules;
    $('body').append(style);

    // Adding the changes to the history for later processing
    this.history[id] = {
      ...this.getData(),
      cssRules,
      // Override the new values over default values
      values: values.reduce((acc, {type, values}) => {
        acc[type] = values;
        return acc;
      }, {}),
    }

    this.postMessageToParentWindow();
  }

  /**
   * Load the external dependencies for color picker
   * */
  loadLibraries() {
    const script = document.createElement('script');
    const link = document.createElement('link');

    script.src = "https://cdn.jsdelivr.net/npm/spectrum-colorpicker2/dist/spectrum.min.js";
    link.href = "https://cdn.jsdelivr.net/npm/spectrum-colorpicker2/dist/spectrum.min.css";
    link.rel = "stylesheet";

    document.body.append(link);
    document.body.append(script);
  }

  /**
   * Get the properties of the currently selected element
  */
  getData(id) {
    // Check the element in history, If its already updated
    let element = this.history[id || this.selectedId];

    if (element) {
      return element;
    }

    // The element is selected for first time so get the default values
    return elements[id || this.selectedId] || {};
  }

  /**
   * Get the jQuery object of currently selected item
  */
  getSelectedEle(id) {
    return $(`.zama-selected[data-zama-id="${id || this.selectedId}"]`);
  }

  /**
   * Attach the click event to the selectable elements
  */
  attachEvents() {
    $('.zama-select').dblclick((e) => {
      e.preventDefault();
      e.stopPropagation();

      let target = e.target;

      // check if the clicked element is the inner element
      if (!$(target).hasClass('zama-select')) {
        const [firstEle = null] = $(target).parents('.zama-select');
        if (!firstEle) return;
        target = $(firstEle);
      }

      // Set the selectedId for using in other places
      this.selectedId = $(target).attr('data-zama-id');
      
      // Deselect the pre-selected element
      $('.zama-selected').removeClass('zama-selected');
      
      // Add a class to the selected element
      $(target).addClass('zama-selected');
      
      // Remove the old popup
      this.setPopup('');

      // Render the popup on the page
      this.createPopup()
    });

    $('main, header, aside').click((e) => {
      this.hidePopup();
    });

    $('*[contenteditable=true]').focus((e) => {
      const ele = e.currentTarget;
      const oldText = $(ele).html();
      $(ele).attr('data-old-text', oldText);
    });

    $('*[contenteditable=true]').blur((e) => {
      const ele = e.currentTarget;
      const oldText = $(ele).attr('data-old-text');
      const newText = $(ele).html();
      
      // If there is value in the "data-my-selector" atttribute, it means the changes should be apply to alll the same selectors and not uniquly.
      const notUnique = $(ele).attr('data-my-selector');

      if (oldText !== newText) {
        let cssSelector = this.getCssSelector(ele);

        if (notUnique) {
          cssSelector = notUnique;
          $(notUnique).html(newText);
        }

        this.textChangeHistory[cssSelector] = {
          oldText,
          newText,
        };

        this.applyStyle();
      }
    });

    $('.global-settings').mouseenter(async () => {
      const gsap = await window.zamaDoc.getGsap();
      $('.global-settings .settings-button').hide();
      $('.global-settings .settings-body').show();
      gsap.fromTo(
        '.global-settings',
        {
          borderRadius: '%50',
          opacity: 0.4
        },
        {
          duration: 0.5,
          opacity: 0.9,
          y: 50,
          width: 180,
          height: 180,
          borderRadius: 0,
        }
      );
    });

    $('.global-settings').mouseleave(async () => {
      const gsap = await window.zamaDoc.getGsap();
      gsap.fromTo(
        '.global-settings',
        {
          borderRadius: 0
        },
        { 
          duration: 0.5,
          y: 0,
          width: 80,
          height: 80,
          borderRadius: '50%',
          onComplete: () => {
            setTimeout(() => {
              gsap.fromTo('.global-settings', { opacity: 0.9}, { duration: 0.2, opacity: 0.4 });
            }, 200);
          }
        }
      );

      $('.global-settings .settings-button').show();
      $('.global-settings .settings-body').hide();
    });

    $('.setting-download').click(() => {
      this.postMessageToParentWindow('download');
    });

    $('.setting-preview').click(() => {
      this.postMessageToParentWindow('preview');
    });

    $('.setting-close').click(() => {
      window.close();
    });

    window.addEventListener('message', (event) => {
      const { eventType, value } = event.data;

      if (eventType === 'download' || eventType === 'preview') {
        window.open(value, '_blank');
      }
    });


    setTimeout(() => {
      $(".api-path-try-btn").off('click');
      $(".path .path-url .link").off('click');
      $('aside .uk-nav a').click(function(e) {
        e.preventDefault();
        $(this).focus();
      });
      window.zamaDoc.initGsap(() => {});
    }, 1000);
  }

  /**
   * Append the popup container to the body
  */
  attachPopup() {
    $('body').append('<div class="zama-popup"></div>');
  }

  /**
   * Show and Set the position of the popup
  */
  showPopup() {
    const { align = 'bottom center', distance = {} } = this.getData();
    // Possible values for alignV: top, center, bottom, above
    // Possible values for alignH: left, center right
    const [alignV = 'bottom', alignH = 'center'] = align.split(' ');
    const { x = 0, y = 0 } = distance;

    let { left = 0, top = 0 } = this.getSelectedEle().offset();
    const [eWidth, eHeight] = [this.getSelectedEle().outerWidth(), this.getSelectedEle().outerHeight()];
    const [popupWidth, popupHeight] = [$('.zama-popup').outerWidth(), $('.zama-popup').outerHeight()];
    
    if (alignV === 'bottom') {
      top += eHeight + 2;
    } else if (alignV === 'center') {
      top += eHeight / 2;
    } else if (alignV === 'top') { 
    } else if (alignV === 'above') {
      top -= popupHeight + 2; 
    }

    if (alignH === 'left') {
      left -= popupWidth + 2;
    } else if (alignH === 'center') {
      left += ((eWidth / 2) - (popupWidth / 2));
    } else if (alignH === 'right') {
      left += eWidth + 2;
    }

    if (align === 'pre' || left < 0) {
      left = 0;
    }

    if (align === 'pre' || top < 0) {
      top = 0;
    }


    $('.zama-popup').css('left', left  + x);
    $('.zama-popup').css('top', top + y);

    $('.zama-popup').show();
  }

  /**
   * Set the inner content of a modal
  */
  setPopup(html) {
    html += `<span uk-icon="close" class="button-close" style="position: absolute; top: 6px; right: 6px;"></span>`; 
    $('.zama-popup').html(html);
  }

  /**
   * Hide the popup
  */
  hidePopup() {
    $('.zama-popup').hide();
  }

  /**
   * Trigger a message to the parent window on change
  */
  postMessageToParentWindow(eventType) {
    let allCssRules = Object.keys(this.history).map(e => this.history[e].cssRules).join('\n');
    let allJsScripts = Object.keys(this.textChangeHistory).map(e => (
      `$(\`${e}\`).html(\`${this.textChangeHistory[e].newText.replace(/`/g, '\\`')}\`);`
    )).join('\n');
    
    if (allCssRules) {
      allCssRules = `<style>\n${allCssRules}\n</style>\n`;
    }

    if (allJsScripts) {
      allJsScripts = `<script>\n${allJsScripts}\n</script>\n`;
    }

    const post = ({ eventType, value }) => {
      if (window.opener) window.opener.postMessage({
        eventType,
        value,
      }, '*');
    }

    post({ eventType: 'customFootScript', value: allCssRules + allJsScripts });

    if (eventType === 'download') {
      post({ eventType: 'download' });
    } else if (eventType === 'preview') {
      post({ eventType: 'preview' });
    }
  }

  /**
   * Get the css selector of the element, the selector is unique and will only target the element passed to this function.
  */
  getCssSelector(ele) {
    if (!(ele instanceof Element)) return;

    let path = [];
    while (ele.nodeType === Node.ELEMENT_NODE) {
      let selector = ele.nodeName.toLowerCase();


      /* For id selector */
      // if (ele.id) {
      //   selector += '#' + ele.id;
      //   path.unshift(selector);
      //   break;
      // } else {
        
      // }
      let sib = ele, nth = 1;

      while (sib = sib.previousElementSibling) {
        if (sib.nodeName.toLowerCase() == selector) nth++;
      }

      if (nth !== 1) {
        selector += ":nth-of-type("+nth+")";
      } else if (nth === 1 && ele.nextElementSibling) {
        selector += ":nth-of-type(1)";
      }

      path.unshift(selector);
      ele = ele.parentNode;
    }

    return path.join(" > ");
  }
}
$(() => {
  const editor = new Editor();
});