@automattic/launchpad 1.2.3 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/cjs/action-components/share-site-modal/index.js +3 -5
  3. package/dist/cjs/action-components/share-site-modal/index.js.map +1 -1
  4. package/dist/cjs/action-components/share-site-modal/style.scss +0 -19
  5. package/dist/cjs/checklist-item/index.js +4 -4
  6. package/dist/cjs/checklist-item/index.js.map +1 -1
  7. package/dist/cjs/setup-actions.js +8 -3
  8. package/dist/cjs/setup-actions.js.map +1 -1
  9. package/dist/esm/action-components/share-site-modal/index.js +3 -5
  10. package/dist/esm/action-components/share-site-modal/index.js.map +1 -1
  11. package/dist/esm/action-components/share-site-modal/style.scss +0 -19
  12. package/dist/esm/checklist-item/index.js +2 -2
  13. package/dist/esm/checklist-item/index.js.map +1 -1
  14. package/dist/esm/setup-actions.js +8 -3
  15. package/dist/esm/setup-actions.js.map +1 -1
  16. package/dist/tsconfig-cjs.tsbuildinfo +1 -1
  17. package/dist/tsconfig.tsbuildinfo +1 -1
  18. package/dist/types/action-components/share-site-modal/index.d.ts +1 -1
  19. package/dist/types/action-components/share-site-modal/index.d.ts.map +1 -1
  20. package/dist/types/checklist/index.d.ts +1 -1
  21. package/dist/types/checklist/index.d.ts.map +1 -1
  22. package/dist/types/checklist-item/index.d.ts.map +1 -1
  23. package/dist/types/launchpad.d.ts +1 -1
  24. package/dist/types/launchpad.d.ts.map +1 -1
  25. package/dist/types/setup-actions.d.ts.map +1 -1
  26. package/package.json +5 -8
  27. package/src/action-components/share-site-modal/index.tsx +2 -13
  28. package/src/action-components/share-site-modal/style.scss +0 -19
  29. package/src/checklist-item/index.tsx +6 -2
  30. package/src/setup-actions.ts +8 -3
  31. package/src/test/setup-actions.ts +44 -0
@@ -6,6 +6,6 @@ interface ShareSiteModalProps {
6
6
  site: SiteDetails | null;
7
7
  task: Task | null;
8
8
  }
9
- declare const ShareSiteModal: ({ setModalIsOpen, site, task }: ShareSiteModalProps) => import("react/jsx-runtime").JSX.Element;
9
+ declare const ShareSiteModal: ({ setModalIsOpen, site, task }: ShareSiteModalProps) => import("react").JSX.Element;
10
10
  export default ShareSiteModal;
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/action-components/share-site-modal/index.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,cAAc,CAAC;AAEtB,UAAU,mBAAmB;IAC5B,cAAc,EAAE,CAAE,MAAM,EAAE,OAAO,KAAM,IAAI,CAAC;IAC5C,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CAClB;AAkHD,QAAA,MAAM,cAAc,GAAK,gCAAgC,mBAAmB,4CA8H3E,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/action-components/share-site-modal/index.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,cAAc,CAAC;AAEtB,UAAU,mBAAmB;IAC5B,cAAc,EAAE,CAAE,MAAM,EAAE,OAAO,KAAM,IAAI,CAAC;IAC5C,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CAClB;AAkHD,QAAA,MAAM,cAAc,GAAK,gCAAgC,mBAAmB,gCAoH3E,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -7,6 +7,6 @@ interface Props {
7
7
  children?: ReactElement<ComponentProps<typeof ChecklistItem>> | ReactElement<ComponentProps<typeof ChecklistItem>>[];
8
8
  }
9
9
  declare const Checklist: FC<Props>;
10
- export declare const Placeholder: () => import("react/jsx-runtime").JSX.Element;
10
+ export declare const Placeholder: () => import("react").JSX.Element;
11
11
  export default Checklist;
12
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checklist/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,EAAE,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAChG,OAAO,aAA0D,MAAM,mBAAmB,CAAC;AAC3F,OAAO,cAAc,CAAC;AAEtB,UAAU,KAAK;IACd,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,EACN,YAAY,CAAE,cAAc,CAAE,OAAO,aAAa,CAAE,CAAE,GACtD,YAAY,CAAE,cAAc,CAAE,OAAO,aAAa,CAAE,CAAE,EAAE,CAAC;CAC5D;AAED,QAAA,MAAM,SAAS,EAAE,EAAE,CAAE,KAAK,CA6BzB,CAAC;AAEF,eAAO,MAAM,WAAW,+CASvB,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checklist/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,EAAE,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAChG,OAAO,aAA0D,MAAM,mBAAmB,CAAC;AAC3F,OAAO,cAAc,CAAC;AAEtB,UAAU,KAAK;IACd,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,EACN,YAAY,CAAE,cAAc,CAAE,OAAO,aAAa,CAAE,CAAE,GACtD,YAAY,CAAE,cAAc,CAAE,OAAO,aAAa,CAAE,CAAE,EAAE,CAAC;CAC5D;AAED,QAAA,MAAM,SAAS,EAAE,EAAE,CAAE,KAAK,CA6BzB,CAAC;AAEF,eAAO,MAAM,WAAW,mCASvB,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checklist-item/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,cAAc,CAAC;AAEtB,UAAU,KAAK;IACd,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,IAAI,EAAE,IAAI,CAAC;IACX,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,aAAa,EAAE,EAAE,CAAE,KAAK,CA8I7B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,EAQzB,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checklist-item/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,cAAc,CAAC;AAEtB,UAAU,KAAK;IACd,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,IAAI,EAAE,IAAI,CAAC;IACX,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,aAAa,EAAE,EAAE,CAAE,KAAK,CAkJ7B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,EAQzB,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -9,6 +9,6 @@ type LaunchpadProps = {
9
9
  onPostFilterTasks?: (tasks: Task[]) => Task[];
10
10
  highlightNextAction?: boolean;
11
11
  };
12
- declare const Launchpad: ({ siteSlug, checklistSlug, launchpadContext, onSiteLaunched, onTaskClick, onPostFilterTasks, highlightNextAction, }: LaunchpadProps) => import("react/jsx-runtime").JSX.Element | null;
12
+ declare const Launchpad: ({ siteSlug, checklistSlug, launchpadContext, onSiteLaunched, onTaskClick, onPostFilterTasks, highlightNextAction, }: LaunchpadProps) => import("react").JSX.Element | null;
13
13
  export default Launchpad;
14
14
  //# sourceMappingURL=launchpad.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"launchpad.d.ts","sourceRoot":"","sources":["../../src/launchpad.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEnD,eAAO,MAAM,UAAU,mBAAwD,CAAC;AAEhF,KAAK,cAAc,GAAG;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,aAAa,CAAE,aAAa,CAAE,CAAC;IAC7C,iBAAiB,CAAC,EAAE,CAAE,KAAK,EAAE,IAAI,EAAE,KAAM,IAAI,EAAE,CAAC;IAChD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,QAAA,MAAM,SAAS,GAAK,qHAQjB,cAAc,mDAkEhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"launchpad.d.ts","sourceRoot":"","sources":["../../src/launchpad.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEnD,eAAO,MAAM,UAAU,mBAAwD,CAAC;AAEhF,KAAK,cAAc,GAAG;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,aAAa,CAAE,aAAa,CAAE,CAAC;IAC7C,iBAAiB,CAAC,EAAE,CAAE,KAAK,EAAE,IAAI,EAAE,KAAM,IAAI,EAAE,CAAC;IAChD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,QAAA,MAAM,SAAS,GAAK,qHAQjB,cAAc,uCAkEhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"setup-actions.d.ts","sourceRoot":"","sources":["../../src/setup-actions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAe/D,eAAO,MAAM,oBAAoB,GAAK,0EAOnC,yBAAyB,KAAI,IAAI,EAoJnC,CAAC"}
1
+ {"version":3,"file":"setup-actions.d.ts","sourceRoot":"","sources":["../../src/setup-actions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAe/D,eAAO,MAAM,oBAAoB,GAAK,0EAOnC,yBAAyB,KAAI,IAAI,EA0JnC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/launchpad",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Launchpad components.",
5
5
  "homepage": "https://github.com/Automattic/wp-calypso",
6
6
  "license": "GPL-2.0-or-later",
@@ -39,21 +39,18 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@automattic/calypso-analytics": "^1.1.5",
42
- "@automattic/calypso-config": "^1.0.0-alpha.0",
43
- "@automattic/components": "^3.0.4",
44
- "@automattic/data-stores": "^3.2.1",
45
- "@automattic/i18n-utils": "^1.2.4",
42
+ "@automattic/data-stores": "^3.2.2",
43
+ "@automattic/i18n-utils": "^1.3.0",
46
44
  "@automattic/typography": "^1.0.0",
47
45
  "@automattic/viewport": "^1.1.1",
48
46
  "@tanstack/react-query": "^5.83.0",
49
47
  "@wordpress/base-styles": "^9.1.0",
50
48
  "@wordpress/components": "^35.0.0",
51
49
  "@wordpress/icons": "^13.3.0",
52
- "@wordpress/url": "^4.48.0",
50
+ "@wordpress/ui": "^0.17.0",
53
51
  "clsx": "^2.1.1",
54
52
  "social-logos": "^3.1.18",
55
53
  "tslib": "^2.8.1",
56
- "utility-types": "^3.10.0",
57
54
  "wpcom-proxy-request": "^7.0.7"
58
55
  },
59
56
  "devDependencies": {
@@ -63,7 +60,7 @@
63
60
  "@storybook/addon-a11y": "^9.1.20",
64
61
  "msw": "^2.1.7",
65
62
  "msw-storybook-addon": "2.0.7",
66
- "postcss": "^8.5.3",
63
+ "postcss": "^8.5.15",
67
64
  "react": "^18.3.1",
68
65
  "react-dom": "^18.3.1",
69
66
  "storybook": "^9.1.20",
@@ -1,5 +1,4 @@
1
1
  import { recordTracksEvent } from '@automattic/calypso-analytics';
2
- import { Popover } from '@automattic/components';
3
2
  import { updateLaunchpadSettings } from '@automattic/data-stores';
4
3
  import { useQueryClient } from '@tanstack/react-query';
5
4
  import {
@@ -12,7 +11,7 @@ import {
12
11
  } from '@wordpress/components';
13
12
  import { __, sprintf } from '@wordpress/i18n';
14
13
  import { copy, share, check } from '@wordpress/icons';
15
- import { useState, useRef, useMemo, useCallback } from 'react';
14
+ import { useState, useMemo, useCallback } from 'react';
16
15
  import { SocialLogo } from 'social-logos';
17
16
  import type { Task } from '../../types';
18
17
  import type { SiteDetails } from '@automattic/data-stores';
@@ -127,7 +126,7 @@ const getShareData = ( site: SiteDetails | null ) => {
127
126
  return {
128
127
  title: siteSlug,
129
128
  text: sprintf(
130
- /* translators: siteSlug is the short form of the site URL with the https:// */
129
+ /* translators: %(siteSlug)s is the short form of the site URL with the https:// */
131
130
  __( 'Please visit my site: %(siteSlug)s', 'launchpad' ),
132
131
  {
133
132
  siteSlug,
@@ -158,7 +157,6 @@ const ShareSiteModal = ( { setModalIsOpen, site, task }: ShareSiteModalProps ) =
158
157
  );
159
158
 
160
159
  const [ clipboardCopied, setClipboardCopied ] = useState( false );
161
- const clipboardTextEl = useRef( null );
162
160
  const copyHandler = () => {
163
161
  navigator.clipboard.writeText( shareData.url );
164
162
  setClipboardCopied( true );
@@ -204,20 +202,11 @@ const ShareSiteModal = ( { setModalIsOpen, site, task }: ShareSiteModalProps ) =
204
202
  >
205
203
  <VStack className="share-site-modal__modal-content" spacing={ 4 }>
206
204
  <VStack className="share-site-modal__modal-actions" spacing={ 4 }>
207
- <Popover
208
- className="share-site-modal__popover"
209
- isVisible={ clipboardCopied }
210
- context={ clipboardTextEl.current }
211
- position="top"
212
- >
213
- { __( 'Copied to clipboard!', 'launchpad' ) }
214
- </Popover>
215
205
  <InputControl
216
206
  className="share-site-modal__modal-input-container"
217
207
  __next40pxDefaultSize
218
208
  value={ shareData.title }
219
209
  label={ __( 'Site URL', 'launchpad' ) }
220
- ref={ clipboardTextEl }
221
210
  readOnly
222
211
  hideLabelFromVision
223
212
  suffix={
@@ -45,22 +45,3 @@
45
45
  text-decoration: underline;
46
46
  }
47
47
  }
48
-
49
- .share-site-modal__popover {
50
- outline: none;
51
- z-index: 100000;
52
- .popover__inner {
53
- border: 0;
54
- box-shadow: none;
55
- border-radius: 2px;
56
- color: var(--color-text-inverted);
57
- background: var(--color-neutral-60);
58
- font-size: $font-body-extra-small;
59
- padding: 6px 10px;
60
- text-align: left;
61
- }
62
-
63
- .popover__arrow {
64
- display: none;
65
- }
66
- }
@@ -1,7 +1,7 @@
1
- import { Badge } from '@automattic/components';
2
1
  import { Button, Icon } from '@wordpress/components';
3
2
  import { __, isRTL, sprintf } from '@wordpress/i18n';
4
3
  import { check, chevronLeft, chevronRight } from '@wordpress/icons';
4
+ import { Badge } from '@wordpress/ui';
5
5
  import clsx from 'clsx';
6
6
  import type { Task, Expandable } from '../types';
7
7
  import type { FC, Key } from 'react';
@@ -137,7 +137,11 @@ const ChecklistItem: FC< Props > = ( {
137
137
  <span className="screen-reader-text">{ getStatusText() }</span>
138
138
  <span aria-hidden="true">{ title }</span>
139
139
  </span>
140
- { task.badge_text ? <Badge type="info-blue">{ task.badge_text }</Badge> : null }
140
+ { task.badge_text ? (
141
+ <Badge className="badge" intent="informational">
142
+ { String( task.badge_text ) }
143
+ </Badge>
144
+ ) : null }
141
145
  { shouldDisplayTaskCounter && (
142
146
  <span className="checklist-item__counter">
143
147
  { task.repetition_count }/{ task.target_repetitions }
@@ -1,7 +1,6 @@
1
1
  import { updateLaunchpadSettings } from '@automattic/data-stores';
2
2
  import { localizeUrl } from '@automattic/i18n-utils';
3
3
  import { isMobile } from '@automattic/viewport';
4
- import { addQueryArgs } from '@wordpress/url';
5
4
  import wpcomRequest from 'wpcom-proxy-request';
6
5
  import type { LaunchpadTaskActionsProps, Task } from './types';
7
6
 
@@ -38,8 +37,14 @@ export const setUpActionsForTasks = ( {
38
37
  const hasCalypsoPath = task.calypso_path !== undefined;
39
38
 
40
39
  if ( uiContext === 'calypso' && hasCalypsoPath ) {
41
- if ( task.id === 'drive_traffic' && ! isMobile() && hasCalypsoPath ) {
42
- task.calypso_path = addQueryArgs( task.calypso_path, { tour: 'marketingConnectionsTour' } );
40
+ const { calypso_path } = task;
41
+ if ( task.id === 'drive_traffic' && ! isMobile() && calypso_path !== undefined ) {
42
+ // Merge the query via a throwaway base, but keep the original string as the base so
43
+ // absolute origins survive, then re-append any fragment.
44
+ const params = new URL( calypso_path, 'http://example.com' ).searchParams;
45
+ params.set( 'tour', 'marketingConnectionsTour' );
46
+ const [ baseAndQuery, fragment = '' ] = calypso_path.split( /(#.*)/s );
47
+ task.calypso_path = `${ baseAndQuery.split( '?' )[ 0 ] }?${ params }${ fragment }`;
43
48
  }
44
49
 
45
50
  // Enable task in 'calypso' context
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+ import { setUpActionsForTasks } from '../setup-actions';
5
+ import type { LaunchpadTaskActionsProps } from '../types';
6
+
7
+ jest.mock( '@automattic/viewport', () => ( { isMobile: jest.fn( () => false ) } ) );
8
+ jest.mock( '@automattic/data-stores', () => ( { updateLaunchpadSettings: jest.fn() } ) );
9
+
10
+ const runDriveTraffic = ( calypso_path: string ) => {
11
+ const props: LaunchpadTaskActionsProps = {
12
+ siteSlug: 'example.wordpress.com',
13
+ tasks: [ { id: 'drive_traffic', completed: false, disabled: false, calypso_path } ],
14
+ tracksData: {
15
+ checklistSlug: 'test',
16
+ launchpadContext: 'test',
17
+ recordTracksEvent: jest.fn(),
18
+ tasklistCompleted: false,
19
+ },
20
+ extraActions: {},
21
+ uiContext: 'calypso',
22
+ };
23
+ return setUpActionsForTasks( props )[ 0 ].calypso_path;
24
+ };
25
+
26
+ describe( 'setUpActionsForTasks: drive_traffic tour query arg', () => {
27
+ it( 'appends the tour arg to a relative path', () => {
28
+ expect( runDriveTraffic( '/marketing/connections/example.wordpress.com' ) ).toBe(
29
+ '/marketing/connections/example.wordpress.com?tour=marketingConnectionsTour'
30
+ );
31
+ } );
32
+
33
+ it( 'preserves the origin and existing query of an absolute URL', () => {
34
+ expect( runDriveTraffic( 'https://example.com/wp-admin/admin.php?page=jetpack-social' ) ).toBe(
35
+ 'https://example.com/wp-admin/admin.php?page=jetpack-social&tour=marketingConnectionsTour'
36
+ );
37
+ } );
38
+
39
+ it( 'keeps the fragment after the query', () => {
40
+ expect( runDriveTraffic( '/marketing/connections/example.wordpress.com#section' ) ).toBe(
41
+ '/marketing/connections/example.wordpress.com?tour=marketingConnectionsTour#section'
42
+ );
43
+ } );
44
+ } );