PluginProbe
AL Pack / 1.1.2
AL Pack v1.1.2
1.3.13 trunk 1.0.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.3.0 1.3.1 1.3.11 1.3.12
alpack / includes / analytics.php

analytics.php in AL Pack 1.1.2, at includes/analytics.php

852 lines 29.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) {
3 exit;
4 }
5
6 /**
7 * Analytics functionality for PressLearn Plugin
8 */
9
10 function presslearn_is_plugin_active_for_analytics() {
11 return get_option('presslearn_analytics_enabled', 'no') === 'yes';
12 }
13
14 /**
15 * Analytics admin styles
16 */
17 function presslearn_analytics_admin_styles() {
18 if (!is_admin()) {
19 return;
20 }
21
22 $screen = get_current_screen();
23 if (!$screen || strpos($screen->id, 'presslearn-analytics') === false) {
24 return;
25 }
26
27 wp_register_style(
28 'presslearn-analytics-admin-css',
29 false,
30 array(),
31 PRESSLEARN_PLUGIN_VERSION
32 );
33 wp_enqueue_style('presslearn-analytics-admin-css');
34
35 $analytics_css = "
36 .analytics-header-stats {
37 display: flex;
38 flex-wrap: wrap;
39 justify-content: space-between;
40 gap: 15px;
41 margin-bottom: 30px;
42 border-bottom: 1px solid #f0f0f0;
43 padding-bottom: 20px;
44 }
45
46 .stats-card {
47 background: #fff;
48 border-radius: 10px;
49 box-shadow: 0 2px 8px rgba(0,0,0,0.08);
50 padding: 20px;
51 flex: 1;
52 min-width: 200px;
53 transition: all 0.3s ease;
54 border: 1px solid #f0f0f0;
55 }
56
57 .stats-card:hover {
58 box-shadow: 0 5px 15px rgba(0,0,0,0.08);
59 transform: translateY(-2px);
60 }
61
62 .stats-card h3 {
63 font-size: 14px;
64 color: #666;
65 margin: 0 0 10px 0;
66 font-weight: normal;
67 }
68
69 .stats-card .stats-value {
70 font-size: 28px;
71 font-weight: bold;
72 color: #333;
73 }
74
75 .stats-card .stats-change {
76 font-size: 13px;
77 margin-top: 10px;
78 display: block;
79 }
80
81 .stats-change.positive {
82 color: #4CAF50;
83 }
84
85 .stats-change.negative {
86 color: #f44336;
87 }
88
89 .stats-change.neutral {
90 color: #607D8B;
91 }
92
93 @media (max-width: 1200px) {
94 .stats-card {
95 min-width: 180px;
96 }
97 }
98
99 @media (max-width: 768px) {
100 .analytics-header-stats {
101 flex-direction: column;
102 }
103 }
104
105 .date-range-selector {
106 display: flex;
107 align-items: center;
108 background: #fff;
109 border-radius: 8px;
110 padding: 15px;
111 box-shadow: 0 2px 8px rgba(0,0,0,0.08);
112 margin-bottom: 20px;
113 border: 1px solid #f0f0f0;
114 }
115
116 .period-buttons {
117 display: flex;
118 gap: 8px;
119 margin-right: 20px;
120 }
121
122 .period-btn, .point-btn {
123 background: #f5f5f5;
124 border: 1px solid #ddd;
125 border-radius: 5px;
126 padding: 8px 14px;
127 font-size: 13px;
128 cursor: pointer;
129 transition: all 0.2s;
130 }
131
132 .period-btn:hover, .point-btn:hover {
133 background: #e9e9e9;
134 }
135
136 .period-btn.active {
137 background: #3498db;
138 color: white;
139 border-color: #3498db;
140 }
141
142 .point-btn {
143 background: #3498db;
144 color: white;
145 border-color: #3498db;
146 }
147
148 .point-btn:hover {
149 background: #2980b9;
150 }
151
152 .date-inputs {
153 display: flex;
154 align-items: center;
155 flex: 1;
156 gap: 10px;
157 }
158
159 .date-inputs input[type='date'] {
160 border: 1px solid #ddd;
161 padding: 7px 10px;
162 border-radius: 5px;
163 }
164
165 @media (max-width: 768px) {
166 .date-range-selector {
167 flex-direction: column;
168 align-items: flex-start;
169 }
170
171 .period-buttons {
172 margin-bottom: 15px;
173 margin-right: 0;
174 }
175
176 .date-inputs {
177 flex-direction: column;
178 align-items: flex-start;
179 width: 100%;
180 }
181
182 .date-inputs input[type='date'] {
183 width: 100%;
184 }
185 }
186
187 .date-range-picker-container {
188 float: right;
189 margin-left: 20px;
190 margin-top: -2px;
191 }
192
193 .chart-period-tabs {
194 display: flex;
195 align-items: center;
196 margin-bottom: 15px;
197 flex-wrap: wrap;
198 justify-content: flex-start;
199 gap: 10px;
200 }
201
202 .chart-tab {
203 display: inline-block;
204 padding: 8px 16px;
205 text-decoration: none;
206 color: #000;
207 background-color: #f8f9fa;
208 border: 1px solid #b5bfc9;
209 border-radius: 4px;
210 font-size: 13px;
211 font-weight: 500;
212 transition: all 0.3s ease;
213 }
214
215 .chart-tab.active {
216 background-color: #2196F3;
217 color: #fff;
218 border-color: #2196F3;
219 }
220
221 .chart-tab:hover:not(.active) {
222 background-color: #e9ecef;
223 }
224
225 .referrer-chart-container {
226 min-height: 300px;
227 height: auto;
228 margin-bottom: 20px;
229 padding: 15px;
230 background: #fff;
231 border-radius: 8px;
232 border: 1px solid #e0e0e0;
233 }
234
235 @media screen and (max-width: 782px) {
236 .chart-period-tabs {
237 flex-direction: column;
238 align-items: flex-start;
239 }
240
241 .period-buttons {
242 display: flex;
243 width: 100%;
244 margin-bottom: 10px;
245 }
246
247 .chart-tab {
248 flex: 1;
249 text-align: center;
250 }
251
252 .date-range-picker-container {
253 float: none;
254 margin-left: 0;
255 margin-top: 10px;
256 width: 100%;
257 }
258
259 .date-inputs {
260 width: 100%;
261 }
262
263 .date-inputs input[type=\"date\"] {
264 flex: 1;
265 }
266
267 .referrer-chart-container {
268 min-height: 250px;
269 padding: 10px;
270 }
271 }
272 ";
273
274 wp_add_inline_style('presslearn-analytics-admin-css', $analytics_css);
275 }
276
277 /**
278 * Analytics admin scripts
279 */
280 function presslearn_analytics_admin_scripts() {
281 if (!is_admin()) {
282 return;
283 }
284
285 $screen = get_current_screen();
286 if (!$screen || strpos($screen->id, 'presslearn-analytics') === false) {
287 return;
288 }
289
290 wp_register_script(
291 'presslearn-analytics-referrer-js',
292 false,
293 array('jquery'),
294 PRESSLEARN_PLUGIN_VERSION,
295 true
296 );
297 wp_enqueue_script('presslearn-analytics-referrer-js');
298
299 $referrer_js = "
300 document.addEventListener('DOMContentLoaded', function() {
301 const toggleButtons = document.querySelectorAll('.toggle-details');
302
303 toggleButtons.forEach(button => {
304 button.addEventListener('click', function() {
305 const index = this.getAttribute('data-index');
306 const detailsRow = document.getElementById('details-' + index);
307 const icon = this.querySelector('.dashicons');
308
309 if (detailsRow.style.display === 'none') {
310 detailsRow.style.display = 'table-row';
311 icon.classList.remove('dashicons-plus');
312 icon.classList.add('dashicons-minus');
313 } else {
314 detailsRow.style.display = 'none';
315 icon.classList.remove('dashicons-minus');
316 icon.classList.add('dashicons-plus');
317 }
318 });
319 });
320 });
321 ";
322
323 wp_add_inline_script('presslearn-analytics-referrer-js', $referrer_js);
324
325 wp_register_script(
326 'presslearn-analytics-date-js',
327 false,
328 array('jquery'),
329 PRESSLEARN_PLUGIN_VERSION,
330 true
331 );
332 wp_enqueue_script('presslearn-analytics-date-js');
333
334 $date_js = "
335 document.addEventListener('DOMContentLoaded', function() {
336 const startDateInput = document.getElementById('start_date');
337 const endDateInput = document.getElementById('end_date');
338 const todayBtn = document.getElementById('today-btn');
339 const chartTabs = document.querySelectorAll('.chart-tab');
340
341 if (startDateInput && endDateInput) {
342 startDateInput.addEventListener('change', function() {
343 endDateInput.min = this.value;
344 });
345
346 endDateInput.addEventListener('change', function() {
347 startDateInput.max = this.value;
348 });
349 }
350
351 if (todayBtn) {
352 todayBtn.addEventListener('click', function() {
353 const today = new Date().toISOString().split('T')[0];
354 if (startDateInput && endDateInput) {
355 startDateInput.value = today;
356 endDateInput.value = today;
357 document.getElementById('date-range-form').submit();
358 }
359 });
360 }
361
362 chartTabs.forEach(function(tab) {
363 if (tab.href && tab.href.includes('chart_period=')) {
364 tab.addEventListener('click', function(e) {
365 e.preventDefault();
366
367 const today = new Date();
368 const todayStr = today.toISOString().split('T')[0];
369 let startDate = todayStr;
370
371 if (this.href.includes('chart_period=daily')) {
372 const startDateObj = new Date(today);
373 startDateObj.setDate(today.getDate() - 30);
374 startDate = startDateObj.toISOString().split('T')[0];
375 } else if (this.href.includes('chart_period=weekly')) {
376 const startDateObj = new Date(today);
377 startDateObj.setDate(today.getDate() - 90);
378 startDate = startDateObj.toISOString().split('T')[0];
379 } else if (this.href.includes('chart_period=yearly')) {
380 const startDateObj = new Date(today);
381 startDateObj.setFullYear(today.getFullYear() - 3);
382 startDate = startDateObj.toISOString().split('T')[0];
383 }
384
385 let newUrl = this.href;
386 if (newUrl.includes('start_date=') || newUrl.includes('end_date=')) {
387 newUrl = newUrl.replace(/[&?]start_date=[^&]*/g, '');
388 newUrl = newUrl.replace(/[&?]end_date=[^&]*/g, '');
389 }
390
391 const separator = newUrl.includes('?') ? '&' : '?';
392 newUrl += separator + 'start_date=' + startDate + '&end_date=' + todayStr;
393
394 window.location.href = newUrl;
395 });
396 }
397 });
398 });
399 ";
400
401 wp_add_inline_script('presslearn-analytics-date-js', $date_js);
402
403 wp_register_script(
404 'presslearn-analytics-banner-js',
405 false,
406 array('jquery'),
407 PRESSLEARN_PLUGIN_VERSION,
408 true
409 );
410 wp_enqueue_script('presslearn-analytics-banner-js');
411
412 $banner_js = "
413 document.addEventListener('DOMContentLoaded', function() {
414 const bannerContainer = document.getElementById('presslearn-banner-container');
415 const banner = document.getElementById('presslearn-banner');
416 const bannerSkeleton = document.getElementById('presslearn-banner-skeleton');
417 const bannerLink = document.getElementById('presslearn-banner-link');
418 const bannerImage = document.getElementById('presslearn-banner-image');
419
420 function fetchBanner() {
421 if (!bannerContainer || !banner || !bannerSkeleton || !bannerLink || !bannerImage) {
422 return;
423 }
424
425 fetch('" . esc_url(rest_url('presslearn/v1/banner')) . "', {
426 method: 'GET',
427 headers: {
428 'Content-Type': 'application/json',
429 }
430 })
431 .then(response => response.json())
432 .then(data => {
433 if (data.success && data.data) {
434 bannerImage.src = data.data.url;
435 bannerLink.href = data.data.href_url;
436 bannerImage.alt = data.data.title || 'PressLearn Banner';
437
438 bannerSkeleton.style.display = 'none';
439 banner.style.display = 'block';
440 } else {
441 bannerContainer.style.display = 'none';
442 }
443 })
444 .catch(error => {
445 console.log('Banner load failed:', error);
446 bannerContainer.style.display = 'none';
447 });
448 }
449
450 if (bannerContainer && banner && bannerSkeleton && bannerLink && bannerImage) {
451 bannerSkeleton.style.display = 'block';
452 banner.style.display = 'none';
453
454 setTimeout(fetchBanner, 100);
455 setInterval(fetchBanner, 300000);
456 }
457 });
458 ";
459
460 wp_add_inline_script('presslearn-analytics-banner-js', $banner_js);
461
462 wp_register_script(
463 'presslearn-analytics-ajax-js',
464 false,
465 array('jquery'),
466 PRESSLEARN_PLUGIN_VERSION,
467 true
468 );
469 wp_enqueue_script('presslearn-analytics-ajax-js');
470
471 wp_localize_script('presslearn-analytics-ajax-js', 'presslearn_ajax', array(
472 'ajax_url' => admin_url('admin-ajax.php'),
473 'nonce' => wp_create_nonce('presslearn_delete_analytics_data_nonce')
474 ));
475
476 $ajax_js = "
477 document.addEventListener('DOMContentLoaded', function() {
478 function confirmDeleteAnalyticsData() {
479 if (confirm('정말로 모든 통계 데이터를 삭제하시겠습니까? 이 작�
480 은 되돌릴 수 없습니다.')) {
481 jQuery.ajax({
482 url: presslearn_ajax.ajax_url,
483 type: 'POST',
484 data: {
485 action: 'presslearn_delete_analytics_data',
486 nonce: presslearn_ajax.nonce
487 },
488 success: function(response) {
489 if (response.success) {
490 alert('통계 데이터가 성공적으로 삭제되었습니다.');
491 location.reload();
492 } else {
493 alert('데이터 삭제 중 오류가 발생했습니다: ' + (response.data || '알 수 없는 오류'));
494 }
495 },
496 error: function() {
497 alert('서버와의 통신 중 오류가 발생했습니다.');
498 }
499 });
500 }
501 }
502
503 const deleteBtn = document.getElementById('delete-analytics-btn');
504 if (deleteBtn) {
505 deleteBtn.addEventListener('click', confirmDeleteAnalyticsData);
506 }
507 });
508 ";
509
510 wp_add_inline_script('presslearn-analytics-ajax-js', $ajax_js);
511 }
512
513 function presslearn_render_analytics_scripts($chart_data, $chart_period, $referrers_to_display) {
514 wp_register_script(
515 'presslearn-analytics-chart-render-js',
516 false,
517 array('jquery'),
518 PRESSLEARN_PLUGIN_VERSION,
519 true
520 );
521 wp_enqueue_script('presslearn-analytics-chart-render-js');
522
523 $chart_js = "
524 document.addEventListener('DOMContentLoaded', function() {
525 if (typeof Chart === 'undefined') {
526 console.error('Chart.js is not loaded');
527 return;
528 }
529
530 document.getElementById('today-btn').addEventListener('click', function() {
531 const today = new Date().toISOString().split('T')[0];
532 document.getElementById('start_date').value = today;
533 document.getElementById('end_date').value = today;
534 document.getElementById('date-range-form').submit();
535 });
536
537 const labels = " . wp_json_encode($chart_data['labels']) . ";
538 const pageviewsData = " . wp_json_encode($chart_data['pageviews']) . ";
539 const visitorsData = " . wp_json_encode($chart_data['visitors']) . ";
540 const ipVisitorsData = " . wp_json_encode($chart_data['ip_visitors']) . ";
541 const rawDates = " . wp_json_encode($chart_data['raw_dates']) . ";
542
543 const ctx = document.getElementById('analyticsChart').getContext('2d');
544 const analyticsChart = new Chart(ctx, {
545 type: 'line',
546 data: {
547 labels: labels,
548 datasets: [
549 {
550 label: '페이지뷰',
551 data: pageviewsData,
552 borderColor: '#2196F3',
553 backgroundColor: (context) => {
554 const chart = context.chart;
555 const {ctx, chartArea} = chart;
556 if (!chartArea) {
557 return 'rgba(33, 150, 243, 0.1)';
558 }
559 const gradient = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom);
560 gradient.addColorStop(0, 'rgba(33, 150, 243, 0.8)');
561 gradient.addColorStop(1, 'rgba(33, 150, 243, 0.02)');
562 return gradient;
563 },
564 borderWidth: 3,
565 fill: true,
566 tension: 0.4,
567 pointRadius: 0,
568 pointHoverRadius: 0
569 },
570 {
571 label: '방문자 수',
572 data: visitorsData,
573 borderColor: '#4CAF50',
574 backgroundColor: (context) => {
575 const chart = context.chart;
576 const {ctx, chartArea} = chart;
577 if (!chartArea) {
578 return 'rgba(76, 175, 80, 0.1)';
579 }
580 const gradient = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom);
581 gradient.addColorStop(0, 'rgba(76, 175, 80, 0.8)');
582 gradient.addColorStop(1, 'rgba(76, 175, 80, 0.02)');
583 return gradient;
584 },
585 borderWidth: 3,
586 fill: true,
587 tension: 0.4,
588 pointRadius: 0,
589 pointHoverRadius: 0
590 },
591 {
592 label: '순 방문자 (IP 기준)',
593 data: ipVisitorsData,
594 borderColor: '#FF9A99',
595 backgroundColor: (context) => {
596 const chart = context.chart;
597 const {ctx, chartArea} = chart;
598 if (!chartArea) {
599 return 'rgba(255, 154, 150, 0.1)';
600 }
601 const gradient = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom);
602 gradient.addColorStop(0, 'rgba(255, 154, 150, 0.8)');
603 gradient.addColorStop(1, 'rgba(255, 154, 150, 0.02)');
604 return gradient;
605 },
606 borderWidth: 3,
607 fill: true,
608 tension: 0.4,
609 pointRadius: 0,
610 pointHoverRadius: 0
611 }
612 ]
613 },
614 options: {
615 responsive: true,
616 maintainAspectRatio: false,
617 hover: {
618 mode: 'index',
619 intersect: false
620 },
621 interaction: {
622 mode: 'index',
623 intersect: false
624 },
625 scales: {
626 y: {
627 beginAtZero: true,
628 grid: {
629 color: 'rgba(0, 0, 0, 0.05)'
630 }
631 },
632 x: {
633 grid: {
634 color: 'rgba(0, 0, 0, 0.05)'
635 },
636 ticks: {
637 maxRotation: 45,
638 minRotation: 0,
639 autoSkip: true,
640 maxTicksLimit: function() {
641 if (rawDates.length > 0 && rawDates[0].period === 'hourly') {
642 return 24;
643 } else if ('" . esc_js($chart_period) . "' === 'weekly') {
644 return 12;
645 } else if ('" . esc_js($chart_period) . "' === 'yearly') {
646 return 12;
647 } else {
648 return Math.min(labels.length, window.innerWidth < 768 ? 7 : 15);
649 }
650 }()
651 }
652 }
653 },
654 plugins: {
655 legend: {
656 position: 'top',
657 align: 'center',
658 labels: {
659 boxWidth: 12,
660 padding: 20,
661 font: {
662 size: 12
663 },
664 usePointStyle: true,
665 pointStyle: 'circle'
666 }
667 },
668 tooltip: {
669 backgroundColor: 'rgba(0, 0, 0, 0.7)',
670 padding: 10,
671 titleFont: {
672 size: 14
673 },
674 bodyFont: {
675 size: 13
676 },
677 displayColors: true,
678 mode: 'index',
679 intersect: false,
680 callbacks: {
681 title: function(tooltipItems) {
682 const idx = tooltipItems[0].dataIndex;
683 if (idx >= 0 && idx < rawDates.length) {
684 const dateInfo = rawDates[idx];
685 const period = dateInfo.period;
686 const startDate = moment(dateInfo.start);
687
688 if (period === 'hourly') {
689 return startDate.format('YYYY�
690 � M월 D일') + ' ' + startDate.format('H시');
691 } else if (period === 'daily') {
692 return startDate.format('YYYY�
693 � M월 D일') + ' ' + getDayOfWeekKorean(startDate.day());
694 } else if (period === 'weekly') {
695 const endDate = moment(dateInfo.end);
696 return startDate.format('YYYY�
697 � M월 D일') + ' ' + getDayOfWeekKorean(startDate.day()) + ' ~ ' +
698 endDate.format('M월 D일') + ' ' + getDayOfWeekKorean(endDate.day()) + ' 주';
699 } else if (period === 'yearly') {
700 return startDate.format('YYYY�
701 �');
702 }
703 }
704 return tooltipItems[0].label;
705 },
706 label: function(context) {
707 let label = context.dataset.label || '';
708 if (label) {
709 label += ': ';
710 }
711 if (context.parsed.y !== null) {
712 label += new Intl.NumberFormat('ko-KR').format(context.parsed.y);
713 }
714 return label;
715 }
716 }
717 }
718 }
719 }
720 });
721
722 function getDayOfWeekKorean(day) {
723 const days = ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일'];
724 return days[day];
725 }
726
727 function resizeChart() {
728 const container = document.querySelector('.chart-container');
729 const canvas = document.getElementById('analyticsChart');
730
731 if (container && canvas) {
732 canvas.style.height = container.offsetHeight + 'px';
733 canvas.style.width = container.offsetWidth + 'px';
734 }
735 }
736
737 window.addEventListener('resize', resizeChart);
738 resizeChart();
739
740 if (document.getElementById('referrerChart')) {
741 const referrerData = " . wp_json_encode($referrers_to_display) . ";
742 const referrerLabels = referrerData.map(item => item.referrer);
743 const referrerCounts = referrerData.map(item => item.count);
744
745 function getPlatformColor(platformName) {
746 const platformColors = {
747 '구글': '#4285F4',
748 '네이버': '#03C75A',
749 '네이버 블로그': '#03C75A',
750 '다음': '#FF6600',
751 '빙': '#00BCF2',
752 '야후': '#720E9E',
753 '페이스북': '#1877F2',
754 '인스타그램': '#E4405F',
755 '트위터': '#1DA1F2',
756 '유튜브': '#FF0000',
757 '카카오톡': '#FEE500',
758 '직접 접속': '#6C757D',
759 '데이터 없음': '#DEE2E6'
760 };
761
762 return platformColors[platformName] || '#6C757D';
763 }
764
765 const backgroundColors = referrerLabels.map(label => getPlatformColor(label));
766 const borderColors = backgroundColors;
767
768 const referrerCtx = document.getElementById('referrerChart').getContext('2d');
769 new Chart(referrerCtx, {
770 type: 'bar',
771 data: {
772 labels: referrerLabels,
773 datasets: [{
774 label: '페이지뷰 수',
775 data: referrerCounts,
776 backgroundColor: backgroundColors,
777 borderColor: borderColors,
778 borderWidth: 1
779 }]
780 },
781 options: {
782 indexAxis: 'y',
783 responsive: true,
784 maintainAspectRatio: false,
785 scales: {
786 x: {
787 beginAtZero: true,
788 grid: {
789 color: 'rgba(0, 0, 0, 0.1)'
790 },
791 ticks: {
792 callback: function(value) {
793 return new Intl.NumberFormat('ko-KR').format(value);
794 }
795 }
796 },
797 y: {
798 grid: {
799 display: false
800 },
801 ticks: {
802 font: {
803 size: 12
804 },
805 maxRotation: 0
806 }
807 }
808 },
809 plugins: {
810 legend: {
811 display: true,
812 position: 'top',
813 align: 'start',
814 labels: {
815 boxWidth: 12,
816 padding: 20,
817 font: {
818 size: 12
819 },
820 usePointStyle: true,
821 pointStyle: 'rect'
822 }
823 },
824 tooltip: {
825 backgroundColor: 'rgba(0, 0, 0, 0.8)',
826 padding: 10,
827 titleFont: {
828 size: 13
829 },
830 bodyFont: {
831 size: 12
832 },
833 callbacks: {
834 label: function(context) {
835 return context.dataset.label + ': ' + new Intl.NumberFormat('ko-KR').format(context.parsed.x) + ' PV';
836 }
837 }
838 }
839 }
840 }
841 });
842 }
843 });
844 ";
845
846 wp_add_inline_script('presslearn-analytics-chart-render-js', $chart_js);
847 }
848
849 add_action('admin_enqueue_scripts', 'presslearn_analytics_admin_styles');
850 add_action('admin_enqueue_scripts', 'presslearn_analytics_admin_scripts');
851
852