Ver código fonte

【UI替换】主页 - 产品互推模块导入

lizhe 1 ano atrás
pai
commit
21207c74c1
17 arquivos alterados com 1735 adições e 36 exclusões
  1. 168 0
      PDF Office/PDF Master.xcodeproj/project.pbxproj
  2. 36 36
      PDF Office/PDF Master/Class/Home/ViewController/KMHomeViewController.swift
  3. 20 0
      PDF Office/PDF Master/Class/Home/ViewController/KMHomeViewController.xib
  4. 43 0
      PDF Office/PDF Master/Class/KMAdvertisement/Cache/KMAdvertisementCache.swift
  5. 175 0
      PDF Office/PDF Master/Class/KMAdvertisement/Config/KMAdvertisementConfig.swift
  6. 269 0
      PDF Office/PDF Master/Class/KMAdvertisement/Manager/KMAdvertisementManager.swift
  7. 92 0
      PDF Office/PDF Master/Class/KMAdvertisement/Model/KMAdvertisementImage.swift
  8. 97 0
      PDF Office/PDF Master/Class/KMAdvertisement/Model/KMAdvertisementModel.swift
  9. 143 0
      PDF Office/PDF Master/Class/KMAdvertisement/Model/KMAdvertisementModelTransition.swift
  10. 106 0
      PDF Office/PDF Master/Class/KMAdvertisement/Model/KMAdvertisementTimeStampConversion.swift
  11. 167 0
      PDF Office/PDF Master/Class/KMAdvertisement/Request/KMAdvertisementRequestServer.swift
  12. 46 0
      PDF Office/PDF Master/Class/KMAdvertisement/View/Cell/KMAdvertisementCollectionHeadView.swift
  13. 32 0
      PDF Office/PDF Master/Class/KMAdvertisement/View/Cell/KMAdvertisementCollectionHeadView.xib
  14. 64 0
      PDF Office/PDF Master/Class/KMAdvertisement/View/Cell/KMAdvertisementCollectionViewItem.swift
  15. 59 0
      PDF Office/PDF Master/Class/KMAdvertisement/View/Cell/KMAdvertisementCollectionViewItem.xib
  16. 161 0
      PDF Office/PDF Master/Class/KMAdvertisement/View/KMAdvertisementTableView.swift
  17. 57 0
      PDF Office/PDF Master/Class/KMAdvertisement/View/KMAdvertisementTableView.xib

+ 168 - 0
PDF Office/PDF Master.xcodeproj/project.pbxproj

@@ -1362,6 +1362,48 @@
 		ADAFDA032AE8BD5C00F084BC /* KMConvertURLToPDF.m in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA022AE8BD5C00F084BC /* KMConvertURLToPDF.m */; };
 		ADAFDA042AE8BD5C00F084BC /* KMConvertURLToPDF.m in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA022AE8BD5C00F084BC /* KMConvertURLToPDF.m */; };
 		ADAFDA052AE8BD5C00F084BC /* KMConvertURLToPDF.m in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA022AE8BD5C00F084BC /* KMConvertURLToPDF.m */; };
+		ADAFDA0D2AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA072AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib */; };
+		ADAFDA0E2AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA072AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib */; };
+		ADAFDA0F2AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA072AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib */; };
+		ADAFDA102AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA082AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib */; };
+		ADAFDA112AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA082AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib */; };
+		ADAFDA122AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA082AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib */; };
+		ADAFDA132AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA092AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift */; };
+		ADAFDA142AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA092AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift */; };
+		ADAFDA152AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA092AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift */; };
+		ADAFDA162AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA0A2AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift */; };
+		ADAFDA172AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA0A2AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift */; };
+		ADAFDA182AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA0A2AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift */; };
+		ADAFDA192AE8DD6600F084BC /* KMAdvertisementTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA0B2AE8DD6600F084BC /* KMAdvertisementTableView.swift */; };
+		ADAFDA1A2AE8DD6600F084BC /* KMAdvertisementTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA0B2AE8DD6600F084BC /* KMAdvertisementTableView.swift */; };
+		ADAFDA1B2AE8DD6600F084BC /* KMAdvertisementTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA0B2AE8DD6600F084BC /* KMAdvertisementTableView.swift */; };
+		ADAFDA1C2AE8DD6600F084BC /* KMAdvertisementTableView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA0C2AE8DD6600F084BC /* KMAdvertisementTableView.xib */; };
+		ADAFDA1D2AE8DD6600F084BC /* KMAdvertisementTableView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA0C2AE8DD6600F084BC /* KMAdvertisementTableView.xib */; };
+		ADAFDA1E2AE8DD6600F084BC /* KMAdvertisementTableView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADAFDA0C2AE8DD6600F084BC /* KMAdvertisementTableView.xib */; };
+		ADAFDA252AE8DE1B00F084BC /* KMAdvertisementModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA212AE8DE1B00F084BC /* KMAdvertisementModel.swift */; };
+		ADAFDA262AE8DE1B00F084BC /* KMAdvertisementModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA212AE8DE1B00F084BC /* KMAdvertisementModel.swift */; };
+		ADAFDA272AE8DE1B00F084BC /* KMAdvertisementModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA212AE8DE1B00F084BC /* KMAdvertisementModel.swift */; };
+		ADAFDA282AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA222AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift */; };
+		ADAFDA292AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA222AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift */; };
+		ADAFDA2A2AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA222AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift */; };
+		ADAFDA2B2AE8DE1B00F084BC /* KMAdvertisementCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA242AE8DE1B00F084BC /* KMAdvertisementCache.swift */; };
+		ADAFDA2C2AE8DE1B00F084BC /* KMAdvertisementCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA242AE8DE1B00F084BC /* KMAdvertisementCache.swift */; };
+		ADAFDA2D2AE8DE1B00F084BC /* KMAdvertisementCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA242AE8DE1B00F084BC /* KMAdvertisementCache.swift */; };
+		ADAFDA302AE8E45000F084BC /* KMAdvertisementConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA2F2AE8E44F00F084BC /* KMAdvertisementConfig.swift */; };
+		ADAFDA312AE8E45000F084BC /* KMAdvertisementConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA2F2AE8E44F00F084BC /* KMAdvertisementConfig.swift */; };
+		ADAFDA322AE8E45000F084BC /* KMAdvertisementConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA2F2AE8E44F00F084BC /* KMAdvertisementConfig.swift */; };
+		ADAFDA342AE8EE9300F084BC /* KMAdvertisementImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA332AE8EE9300F084BC /* KMAdvertisementImage.swift */; };
+		ADAFDA352AE8EE9300F084BC /* KMAdvertisementImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA332AE8EE9300F084BC /* KMAdvertisementImage.swift */; };
+		ADAFDA362AE8EE9300F084BC /* KMAdvertisementImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA332AE8EE9300F084BC /* KMAdvertisementImage.swift */; };
+		ADAFDA392AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA382AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift */; };
+		ADAFDA3A2AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA382AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift */; };
+		ADAFDA3B2AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA382AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift */; };
+		ADAFDA3E2AE8F32400F084BC /* KMAdvertisementManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA3D2AE8F32400F084BC /* KMAdvertisementManager.swift */; };
+		ADAFDA3F2AE8F32400F084BC /* KMAdvertisementManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA3D2AE8F32400F084BC /* KMAdvertisementManager.swift */; };
+		ADAFDA402AE8F32400F084BC /* KMAdvertisementManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA3D2AE8F32400F084BC /* KMAdvertisementManager.swift */; };
+		ADAFDA422AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA412AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift */; };
+		ADAFDA432AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA412AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift */; };
+		ADAFDA442AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADAFDA412AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift */; };
 		ADB2D6E6294740F30029D2B3 /* KMPrintPaperSetWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADB2D6E4294740F30029D2B3 /* KMPrintPaperSetWindowController.swift */; };
 		ADB2D6E7294740F30029D2B3 /* KMPrintPaperSetWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADB2D6E4294740F30029D2B3 /* KMPrintPaperSetWindowController.swift */; };
 		ADB2D6E8294740F30029D2B3 /* KMPrintPaperSetWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADB2D6E4294740F30029D2B3 /* KMPrintPaperSetWindowController.swift */; };
@@ -3728,6 +3770,20 @@
 		ADAFD9F62AE68A8500F084BC /* KMCreatPDFView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMCreatPDFView.xib; sourceTree = "<group>"; };
 		ADAFDA012AE8BD5B00F084BC /* KMConvertURLToPDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KMConvertURLToPDF.h; sourceTree = "<group>"; };
 		ADAFDA022AE8BD5C00F084BC /* KMConvertURLToPDF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KMConvertURLToPDF.m; sourceTree = "<group>"; };
+		ADAFDA072AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMAdvertisementCollectionViewItem.xib; sourceTree = "<group>"; };
+		ADAFDA082AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMAdvertisementCollectionHeadView.xib; sourceTree = "<group>"; };
+		ADAFDA092AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementCollectionViewItem.swift; sourceTree = "<group>"; };
+		ADAFDA0A2AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementCollectionHeadView.swift; sourceTree = "<group>"; };
+		ADAFDA0B2AE8DD6600F084BC /* KMAdvertisementTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementTableView.swift; sourceTree = "<group>"; };
+		ADAFDA0C2AE8DD6600F084BC /* KMAdvertisementTableView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMAdvertisementTableView.xib; sourceTree = "<group>"; };
+		ADAFDA212AE8DE1B00F084BC /* KMAdvertisementModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementModel.swift; sourceTree = "<group>"; };
+		ADAFDA222AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementModelTransition.swift; sourceTree = "<group>"; };
+		ADAFDA242AE8DE1B00F084BC /* KMAdvertisementCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementCache.swift; sourceTree = "<group>"; };
+		ADAFDA2F2AE8E44F00F084BC /* KMAdvertisementConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementConfig.swift; sourceTree = "<group>"; };
+		ADAFDA332AE8EE9300F084BC /* KMAdvertisementImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementImage.swift; sourceTree = "<group>"; };
+		ADAFDA382AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementRequestServer.swift; sourceTree = "<group>"; };
+		ADAFDA3D2AE8F32400F084BC /* KMAdvertisementManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementManager.swift; sourceTree = "<group>"; };
+		ADAFDA412AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMAdvertisementTimeStampConversion.swift; sourceTree = "<group>"; };
 		ADB2D6E4294740F30029D2B3 /* KMPrintPaperSetWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPrintPaperSetWindowController.swift; sourceTree = "<group>"; };
 		ADB2D6E5294740F30029D2B3 /* KMPrintPaperSetWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMPrintPaperSetWindowController.xib; sourceTree = "<group>"; };
 		ADB2D6EC2947415E0029D2B3 /* KMPrintPaperSetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPrintPaperSetView.swift; sourceTree = "<group>"; };
@@ -5913,6 +5969,70 @@
 			path = Model;
 			sourceTree = "<group>";
 		};
+		ADAFDA062AE8DD6600F084BC /* Cell */ = {
+			isa = PBXGroup;
+			children = (
+				ADAFDA072AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib */,
+				ADAFDA082AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib */,
+				ADAFDA092AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift */,
+				ADAFDA0A2AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift */,
+			);
+			path = Cell;
+			sourceTree = "<group>";
+		};
+		ADAFDA1F2AE8DD6B00F084BC /* View */ = {
+			isa = PBXGroup;
+			children = (
+				ADAFDA062AE8DD6600F084BC /* Cell */,
+				ADAFDA0B2AE8DD6600F084BC /* KMAdvertisementTableView.swift */,
+				ADAFDA0C2AE8DD6600F084BC /* KMAdvertisementTableView.xib */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		ADAFDA202AE8DE1B00F084BC /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				ADAFDA412AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift */,
+				ADAFDA332AE8EE9300F084BC /* KMAdvertisementImage.swift */,
+				ADAFDA212AE8DE1B00F084BC /* KMAdvertisementModel.swift */,
+				ADAFDA222AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		ADAFDA232AE8DE1B00F084BC /* Cache */ = {
+			isa = PBXGroup;
+			children = (
+				ADAFDA242AE8DE1B00F084BC /* KMAdvertisementCache.swift */,
+			);
+			path = Cache;
+			sourceTree = "<group>";
+		};
+		ADAFDA2E2AE8E44200F084BC /* Config */ = {
+			isa = PBXGroup;
+			children = (
+				ADAFDA2F2AE8E44F00F084BC /* KMAdvertisementConfig.swift */,
+			);
+			path = Config;
+			sourceTree = "<group>";
+		};
+		ADAFDA372AE8EEED00F084BC /* Request */ = {
+			isa = PBXGroup;
+			children = (
+				ADAFDA382AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift */,
+			);
+			path = Request;
+			sourceTree = "<group>";
+		};
+		ADAFDA3C2AE8F31400F084BC /* Manager */ = {
+			isa = PBXGroup;
+			children = (
+				ADAFDA3D2AE8F32400F084BC /* KMAdvertisementManager.swift */,
+			);
+			path = Manager;
+			sourceTree = "<group>";
+		};
 		ADB2D6E229473FF00029D2B3 /* DealPaper */ = {
 			isa = PBXGroup;
 			children = (
@@ -6432,6 +6552,12 @@
 		ADE8BC3629F9453A00570F89 /* KMAdvertisement */ = {
 			isa = PBXGroup;
 			children = (
+				ADAFDA3C2AE8F31400F084BC /* Manager */,
+				ADAFDA372AE8EEED00F084BC /* Request */,
+				ADAFDA2E2AE8E44200F084BC /* Config */,
+				ADAFDA232AE8DE1B00F084BC /* Cache */,
+				ADAFDA202AE8DE1B00F084BC /* Model */,
+				ADAFDA1F2AE8DD6B00F084BC /* View */,
 				ADE8BC3A29F9458700570F89 /* KMRecommondInfo.h */,
 				ADE8BC3929F9458700570F89 /* KMRecommondInfo.m */,
 				ADE8BC3829F9458700570F89 /* KMRecommondManager.h */,
@@ -8464,7 +8590,10 @@
 				ADBC373729CA975B00D93208 /* KMCompatative.xcassets in Resources */,
 				BBC3481F295593F0008D2CD1 /* KMBackgroundListController.xib in Resources */,
 				ADBC372D29CA951E00D93208 /* KMComparativeOutlineView.xib in Resources */,
+				ADAFDA102AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib in Resources */,
+				ADAFDA1C2AE8DD6600F084BC /* KMAdvertisementTableView.xib in Resources */,
 				BB7F7BFA29AA469F00A3E4E7 /* KMSigntureViewItem.xib in Resources */,
+				ADAFDA0D2AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib in Resources */,
 				9F1F82E62934D5240092C4B4 /* KMHomeExtractActionViewController.xib in Resources */,
 				ADAFD9F72AE68A8500F084BC /* KMCreatPDFView.xib in Resources */,
 				89E4E77C2967B370002DBA6F /* KMDynamicStampViewController.xib in Resources */,
@@ -8738,6 +8867,7 @@
 				AD8810A429A8459000178CA1 /* KMComparativeTableViewController.xib in Resources */,
 				AD0FA4F629A8582C00EDEB50 /* KMComparativeTableView.xib in Resources */,
 				BB7507ED29861C37002DBDB1 /* PasswordWindowController.xib in Resources */,
+				ADAFDA112AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib in Resources */,
 				ADD1B6CC2942E85300C3FFF7 /* KMPrintBottomView.xib in Resources */,
 				9F0CB4732967E63100007028 /* KMPropertiesPanelNameSubVC.xib in Resources */,
 				9FF94F1529A7476000B1EF69 /* KMDesignPropertySelector.xib in Resources */,
@@ -8753,6 +8883,7 @@
 				BBEC00D5295C33D600A26C98 /* KMCreateBatesController.xib in Resources */,
 				AD1CA3FB2A05FCB60070541F /* KMAnnotationScreenViewController.xib in Resources */,
 				ADD1B6C02942DD3D00C3FFF7 /* KMPrintChooseView.xib in Resources */,
+				ADAFDA0E2AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib in Resources */,
 				8997012328F41AB8009AF911 /* KMLeftSideViewController.xib in Resources */,
 				BB2F615C2966B69D001CB369 /* KMWatermarkPropertyHomeController.xib in Resources */,
 				BBFBE74C28DD7DE4008B2335 /* Assets.xcassets in Resources */,
@@ -8880,6 +9011,7 @@
 				9FDD0F68294AB645000C4DAD /* KMMainViewController.xib in Resources */,
 				F356720929AF184A00740FF3 /* CPDFListAnnotationNoteWindowController.xib in Resources */,
 				9FDD0FA32952FF4D000C4DAD /* $themes.json in Resources */,
+				ADAFDA1D2AE8DD6600F084BC /* KMAdvertisementTableView.xib in Resources */,
 				9F0CB4B92977BC1000007028 /* KMPropertiesPanelPreviewSubVC.xib in Resources */,
 				9F8539FD2947137500DF644E /* throbber_waiting.png in Resources */,
 				9F8539E42947126000DF644E /* KMChromiumToolbar.xib in Resources */,
@@ -9049,7 +9181,10 @@
 				9F78EFC028F7C1CC001E66F4 /* KMHomeViewController.xib in Resources */,
 				9F8539E52947126000DF644E /* KMChromiumToolbar.xib in Resources */,
 				9F0CB4742967E63100007028 /* KMPropertiesPanelNameSubVC.xib in Resources */,
+				ADAFDA122AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib in Resources */,
+				ADAFDA1E2AE8DD6600F084BC /* KMAdvertisementTableView.xib in Resources */,
 				89E4E6E82963CD82002DBA6F /* KMGeneralAnnotationViewController.xib in Resources */,
+				ADAFDA0F2AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.xib in Resources */,
 				BBEC00D6295C33D600A26C98 /* KMCreateBatesController.xib in Resources */,
 				ADAFD9F92AE68A8500F084BC /* KMCreatPDFView.xib in Resources */,
 				9F1F82E82934D5240092C4B4 /* KMHomeExtractActionViewController.xib in Resources */,
@@ -9395,6 +9530,7 @@
 				89DB5DA9291B8DE70029624F /* KMOutlineEditViewController.swift in Sources */,
 				BB6DD80C29347F77001F0544 /* KMSecureEncryptWindowController.swift in Sources */,
 				BBB14A572978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift in Sources */,
+				ADAFDA132AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift in Sources */,
 				899E0B092919244500B13D34 /* KMCustomTableRowView.swift in Sources */,
 				BBB9B30D299A5D6D004F3235 /* KMCloudUploadOperationQueue.m in Sources */,
 				BB146FC6299DC0D100784A6A /* GTMSessionFetcherService.m in Sources */,
@@ -9435,6 +9571,7 @@
 				BBF38A5A294F2B760086D025 /* KMWatermarkPositionView.swift in Sources */,
 				BBB7B4912A03AD2A00B58A5A /* KMPDFEditToolbar.swift in Sources */,
 				ADC63E372A49813E00854E02 /* KMSubscribeSuccessWindowController.swift in Sources */,
+				ADAFDA252AE8DE1B00F084BC /* KMAdvertisementModel.swift in Sources */,
 				BB8F4586295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift in Sources */,
 				ADF9ED2F29A8507400C4A943 /* KMAccountInfoView.swift in Sources */,
 				9FDD0FAE29534FDC000C4DAD /* KMCompLight.swift in Sources */,
@@ -9520,6 +9657,7 @@
 				AD5999362AD7D9C200412F8B /* KMPropertiesViewPopController.swift in Sources */,
 				BB6719F92AD2CC05003D44D5 /* CPDFSignatureWidgetAnnotation+PDFListView.swift in Sources */,
 				ADDEEA7A2AD3F4C800EF675D /* KMPopUpButton.swift in Sources */,
+				ADAFDA282AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift in Sources */,
 				ADC63E482A49BEDD00854E02 /* KMSubscribeWaterMarkCollectionItem.swift in Sources */,
 				89752E1D2942CB03003FF08E /* KMSearchMode.swift in Sources */,
 				AD3A3587294C11ED00D72802 /* KMPrintPreviewPresenter.swift in Sources */,
@@ -9534,6 +9672,7 @@
 				BB49ED0E293F462E00C82CA2 /* KMConvertImageWindowController.swift in Sources */,
 				ADE3C1C129A4C13700793B13 /* KMPrintAccessoryController_OC.m in Sources */,
 				8942F7F82926089200389627 /* KMSignatureViewController.swift in Sources */,
+				ADAFDA392AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift in Sources */,
 				9F0CB5092986563300007028 /* KMDesignToken+BorderBottom.swift in Sources */,
 				9F1FE4E429406E4700E952CA /* GTMNSColor+Luminance.m in Sources */,
 				BBA5429C29F13A140041BAD0 /* KMMemorandumPattern.swift in Sources */,
@@ -9586,6 +9725,7 @@
 				ADA9102A2A272CE2003352F0 /* KMEditPDFTextManager.swift in Sources */,
 				BB897229294B08720045787C /* KMWatermarkAdjectiveTopBarItemModel.swift in Sources */,
 				BB00301D298CB799002DD1A0 /* KMPreferenceManager.swift in Sources */,
+				ADAFDA342AE8EE9300F084BC /* KMAdvertisementImage.swift in Sources */,
 				ADBC2D28299DCA76006280C8 /* NSTextField+Layer.swift in Sources */,
 				ADF6B8762A48155E0090CB78 /* KMComparativeViewCollectionItem.swift in Sources */,
 				BB49ECF1293F40F500C82CA2 /* KMConvertPageRangeSettingItemView.swift in Sources */,
@@ -9620,6 +9760,7 @@
 				BB6DD821293497B6001F0544 /* KMSecureEncryptModel.swift in Sources */,
 				ADBC373229CA95AA00D93208 /* KMComparativeModel.swift in Sources */,
 				9FCFEC802AD0E74C00EAD2CB /* KMPopMenuButtonCell.swift in Sources */,
+				ADAFDA2B2AE8DE1B00F084BC /* KMAdvertisementCache.swift in Sources */,
 				9FCFEC7C2AC579F600EAD2CB /* CPDFListSignatureAnnotation.swift in Sources */,
 				ADD1B6E42946C00800C3FFF7 /* KMPrintChoosePageSizePosterView.swift in Sources */,
 				9F1FE4BA29406E4700E952CA /* NSImage+CTAdditions.m in Sources */,
@@ -9637,6 +9778,7 @@
 				ADBC2D11299CCD05006280C8 /* KMTextfieldButton.swift in Sources */,
 				BB7BC4DC2AD3FFC200D6BEE6 /* NSImage+ KMExtension.swift in Sources */,
 				9FCFEC982AD14EEF00EAD2CB /* KMMailHelper.swift in Sources */,
+				ADAFDA302AE8E45000F084BC /* KMAdvertisementConfig.swift in Sources */,
 				9FAAA325290A69920046FFCE /* KMToolSetScroller.swift in Sources */,
 				AD0FA51229A9FA8600EDEB50 /* KMResetPasswordView.swift in Sources */,
 				9FDD0F882952FCC6000C4DAD /* KMCompLightParser.swift in Sources */,
@@ -9677,6 +9819,7 @@
 				9F5664872988B16F00020985 /* KMTextfieldVC.swift in Sources */,
 				9F1F82DA292F84D60092C4B4 /* KMHomeInsertActionViewController.swift in Sources */,
 				9FD0D2AF2AD51BCC00DA3FF8 /* CPDFListEditAnnotationViewController.swift in Sources */,
+				ADAFDA422AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift in Sources */,
 				9F0CB4E92986559400007028 /* KMDesignToken+PaddingBottom.swift in Sources */,
 				ADD1B6E82946C02600C3FFF7 /* KMPrintChoosePageSizeMultipageView.swift in Sources */,
 				9F1FE4ED29406E4700E952CA /* ThrobberView.m in Sources */,
@@ -9807,12 +9950,14 @@
 				ADB2D6F9294882AE0029D2B3 /* KMTextFieldStepperView.swift in Sources */,
 				9F72D2082994BDAF00DCACF1 /* KMNotificationVC.swift in Sources */,
 				BB4DD04B299B296500E80DF6 /* KMCloudPathControl.swift in Sources */,
+				ADAFDA192AE8DD6600F084BC /* KMAdvertisementTableView.swift in Sources */,
 				AD867F9029D9554F00F00440 /* KMBOTAOutlineItem.swift in Sources */,
 				BB0A823229C00400002C5C1B /* KMCommonEnum.swift in Sources */,
 				BB49ED06293F461500C82CA2 /* KMConvertCSVWindowController.swift in Sources */,
 				BBC3483B2955A60B008D2CD1 /* KMBackgroundPropertyInfoController.swift in Sources */,
 				AD88109229A7612000178CA1 /* KMRegisterModel.swift in Sources */,
 				ADBC2D1F299CDA29006280C8 /* NSView+Layer.swift in Sources */,
+				ADAFDA3E2AE8F32400F084BC /* KMAdvertisementManager.swift in Sources */,
 				AD1CA3F72A05FCB60070541F /* KMAnnotationScreenViewController.swift in Sources */,
 				ADB2D6E6294740F30029D2B3 /* KMPrintPaperSetWindowController.swift in Sources */,
 				BB897271294DB6BE0045787C /* KMWatermarkAdjectivePlainView.swift in Sources */,
@@ -9969,6 +10114,7 @@
 				BB89725E294C5DDA0045787C /* KMWatermarkPropertyInfoController.swift in Sources */,
 				BB146FAB299DC0D000784A6A /* GTLRBatchQuery.m in Sources */,
 				BB897218294AED6C0045787C /* KMWatermarkAdjectivePreViewBaseController.swift in Sources */,
+				ADAFDA162AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift in Sources */,
 				ADE8BC2F29F8CD7200570F89 /* KMPDFThumbnailModel.swift in Sources */,
 				BB4EEF4029764FCC003A3537 /* KMWatermarkColorView.swift in Sources */,
 				BB146FC9299DC0D100784A6A /* GTMSessionFetcher.m in Sources */,
@@ -10069,6 +10215,7 @@
 				ADBC373D29CA9AE100D93208 /* KMComparativeManager.swift in Sources */,
 				BB147009299DC0D100784A6A /* OIDRegistrationRequest.m in Sources */,
 				BBBB6CDB2AD15B900035AA66 /* CPDFFreeTextAnnotation+PDFListView.swift in Sources */,
+				ADAFDA3F2AE8F32400F084BC /* KMAdvertisementManager.swift in Sources */,
 				BBA19F4829AE27DA001A285A /* KMAnnotationTableRowView.swift in Sources */,
 				BB8F4566295AA3ED0037EA22 /* KMHeaderFooterManager.swift in Sources */,
 				BB99ACC3292DE22E0048AFD9 /* KMMergeViewController.swift in Sources */,
@@ -10187,6 +10334,7 @@
 				BB31981B2AC567B600107371 /* CPDFSelection+PDFListView.swift in Sources */,
 				9FDD0F65294AB645000C4DAD /* KMMainViewController.swift in Sources */,
 				9FCFEC692AC2EAD500EAD2CB /* CPDFListViewColorMenuItemView.swift in Sources */,
+				ADAFDA262AE8DE1B00F084BC /* KMAdvertisementModel.swift in Sources */,
 				ADBC372A29CA950500D93208 /* KMComparativeOutlineView.swift in Sources */,
 				9FDD0FA729533494000C4DAD /* KMJSONParser.swift in Sources */,
 				9FDD0F70294AD13C000C4DAD /* KMMainViewController+Action.swift in Sources */,
@@ -10194,6 +10342,7 @@
 				AD0E8AB12A31B76300DBFD3C /* KMInAppPurchaseManager.swift in Sources */,
 				BBB9B314299A5D6D004F3235 /* DropboxModel.m in Sources */,
 				BBB9B323299A5D6D004F3235 /* KMServicesCloudFile.m in Sources */,
+				ADAFDA3A2AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift in Sources */,
 				BBC745EB295F067B0072C2ED /* KMCropSettingWindowController.swift in Sources */,
 				ADDEEA7B2AD3F4C800EF675D /* KMPopUpButton.swift in Sources */,
 				BBC3480D29558DC1008D2CD1 /* KMBackgroundController.swift in Sources */,
@@ -10252,6 +10401,7 @@
 				BB0A55222A30968900B6E84B /* KMDesignBaseView.swift in Sources */,
 				9FCFEC992AD14EEF00EAD2CB /* KMMailHelper.swift in Sources */,
 				89E4E6ED2963D1B7002DBA6F /* KMColorPickerViewController.m in Sources */,
+				ADAFDA172AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift in Sources */,
 				89752E1E2942CB04003FF08E /* KMSearchMode.swift in Sources */,
 				AD3A3588294C11ED00D72802 /* KMPrintPreviewPresenter.swift in Sources */,
 				BB49ED1A293F4D4E00C82CA2 /* KMConvertCSVSettingView.swift in Sources */,
@@ -10262,6 +10412,7 @@
 				BBA5429D29F13A140041BAD0 /* KMMemorandumPattern.swift in Sources */,
 				BB3A81AD2AC2A4E4006FC66C /* NSTextView+KMExtension.swift in Sources */,
 				BB49ED0F293F462E00C82CA2 /* KMConvertImageWindowController.swift in Sources */,
+				ADAFDA142AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift in Sources */,
 				89E4E7362964148E002DBA6F /* KMAnnotationPropertiesViewController.m in Sources */,
 				9F221ED829A9EC0900978A59 /* KMFillSignTextPanel.swift in Sources */,
 				ADC63E492A49BEDD00854E02 /* KMSubscribeWaterMarkCollectionItem.swift in Sources */,
@@ -10271,6 +10422,7 @@
 				BB003027298CF7EC002DD1A0 /* KMPreferenceDisplayController.swift in Sources */,
 				F36AD77829642FE80015AD53 /* CPDFListView+UndoManager.m in Sources */,
 				BB89726A294DB41D0045787C /* KMWatermarkAdjectivePositionView.swift in Sources */,
+				ADAFDA312AE8E45000F084BC /* KMAdvertisementConfig.swift in Sources */,
 				ADE787A32AA5A833002EC85A /* KMAccountExceptionWindowController.swift in Sources */,
 				BB146FBB299DC0D100784A6A /* GTLRBase64.m in Sources */,
 				BB2C6ACE28F41B9F00478A33 /* CPDFListView.m in Sources */,
@@ -10363,6 +10515,7 @@
 				9F1FE49429406E4700E952CA /* common.m in Sources */,
 				AD0FA51329A9FA8600EDEB50 /* KMResetPasswordView.swift in Sources */,
 				9F0201732A1B488C00C9B673 /* KMAITranslationVC.swift in Sources */,
+				ADAFDA1A2AE8DD6600F084BC /* KMAdvertisementTableView.swift in Sources */,
 				9FD0D2AC2AD5143D00DA3FF8 /* KMTableRowView.swift in Sources */,
 				BBFBE74728DD7DB7008B2335 /* ViewController.swift in Sources */,
 				9FDD0F812952FC36000C4DAD /* KMDesignToken.swift in Sources */,
@@ -10462,6 +10615,7 @@
 				BB6DD81929348A00001F0544 /* KMSecureEncryptComboBoxCellView.swift in Sources */,
 				BBC2BCC7295DA8F30036B983 /* KMCropPreviewController.swift in Sources */,
 				ADE3C1FE29A5C44700793B13 /* KMLightMemberManager.swift in Sources */,
+				ADAFDA2C2AE8DE1B00F084BC /* KMAdvertisementCache.swift in Sources */,
 				BB14701B299DC0D100784A6A /* OIDURLSessionProvider.m in Sources */,
 				9F8DDF352924DA6B006CDC73 /* KMPDFToolsCollectionView.swift in Sources */,
 				BBEC00A5295BD42D00A26C98 /* KMHeaderFooterPageInfoView.swift in Sources */,
@@ -10482,6 +10636,7 @@
 				9FCFEC752AC56ECE00EAD2CB /* CPDFListStampAnnotation.swift in Sources */,
 				9F0CB5162986566D00007028 /* KMDesignToken+BorderRadiusTopLeft.swift in Sources */,
 				AD867F8729D94F5100F00440 /* KMBOTAOutlineView.swift in Sources */,
+				ADAFDA292AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift in Sources */,
 				9F0CB536298656F900007028 /* KMDesignToken+BorderWidthLeft.swift in Sources */,
 				BBA8B7AB2935DC120097D183 /* KMRemovePasswordResultTipView.swift in Sources */,
 				9F02017F2A1BAC1600C9B673 /* KMAIRewritingVC.swift in Sources */,
@@ -10614,6 +10769,7 @@
 				BB146FEB299DC0D100784A6A /* GTLRDuration.m in Sources */,
 				BB89726E294DB67D0045787C /* KMWatermarkAdjectiveBaseView.swift in Sources */,
 				89D2D2C6294972B900BFF5FE /* KMFormCellView.swift in Sources */,
+				ADAFDA432AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift in Sources */,
 				BB146FFD299DC0D100784A6A /* OIDAuthState+Mac.m in Sources */,
 				BB897225294B07960045787C /* KMWatermarkAdjectiveTopBarItemView.swift in Sources */,
 				ADDEEA6F2AD3E16100EF675D /* KMSigntureViewItem.swift in Sources */,
@@ -10666,6 +10822,7 @@
 				9F1FE49D29406E4700E952CA /* HoverCloseButton.m in Sources */,
 				9F1F82C4292F113A0092C4B4 /* KMHomeDragView.swift in Sources */,
 				BB3A81B12AC2B82A006FC66C /* KMPageSizeTool.swift in Sources */,
+				ADAFDA352AE8EE9300F084BC /* KMAdvertisementImage.swift in Sources */,
 				9F1F82CB292F6CF90092C4B4 /* KMPDFInsertPageWindow.swift in Sources */,
 				BB6CA4CD298BB0D000A13864 /* KMPreferenceWindowController.swift in Sources */,
 				ADB5E51A2A3711CB007110A8 /* KMSubscribeWaterMarkView.swift in Sources */,
@@ -10819,6 +10976,8 @@
 				9FCFECA62AD237B500EAD2CB /* KMBatchTableRowView.swift in Sources */,
 				BB93CDEB2AE7B6E100B29C57 /* KMToolbarView.swift in Sources */,
 				BB1EC8002967B26700EC0BC3 /* KMPDFEditViewController.swift in Sources */,
+				ADAFDA402AE8F32400F084BC /* KMAdvertisementManager.swift in Sources */,
+				ADAFDA152AE8DD6600F084BC /* KMAdvertisementCollectionViewItem.swift in Sources */,
 				AD015FB929AB484400A57062 /* KMLightMemberConfig.swift in Sources */,
 				ADBC2D13299CCD05006280C8 /* KMTextfieldButton.swift in Sources */,
 				BB162E90294FFC0C0088E9D1 /* KMWatermarkPDFView.swift in Sources */,
@@ -10843,6 +11002,7 @@
 				BB897243294C028A0045787C /* KMWatermarkAdjectiveSegementControl.swift in Sources */,
 				ADE3C1EF29A5AFB100793B13 /* KMRequestServerManager.swift in Sources */,
 				9F1FE4B629406E4700E952CA /* CTBrowser.m in Sources */,
+				ADAFDA2A2AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift in Sources */,
 				ADC63E412A49816900854E02 /* KMSubscribeSuccessView.swift in Sources */,
 				BBA19F4529ADE6A3001A285A /* KMBookMarkRowView.swift in Sources */,
 				9F0201982A1F352100C9B673 /* KMAITranslationConfirmWindowController.swift in Sources */,
@@ -10872,6 +11032,7 @@
 				ADBC375229CAE27900D93208 /* KMComparativeOutlineRowView.swift in Sources */,
 				ADE8BC3129F8CD7200570F89 /* KMPDFThumbnailModel.swift in Sources */,
 				BB89DD802953F863007C3FFA /* KMWatermarkFileOutsideView.swift in Sources */,
+				ADAFDA442AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift in Sources */,
 				BB6B4C0A292F53CE0071CA06 /* KMMergeFileModel.swift in Sources */,
 				9F0CB4B72977BC1000007028 /* KMPropertiesPanelPreviewSubVC.swift in Sources */,
 				BB3A81B72AC2C0F4006FC66C /* NSObject+KMExtension.swift in Sources */,
@@ -10955,6 +11116,7 @@
 				BBFE6E772930E53000142C01 /* KMMergePopoverViewController.swift in Sources */,
 				ADF6B8782A48155E0090CB78 /* KMComparativeViewCollectionItem.swift in Sources */,
 				BB32BF252A5EA05900D11348 /* KMAnalytics.swift in Sources */,
+				ADAFDA1B2AE8DD6600F084BC /* KMAdvertisementTableView.swift in Sources */,
 				89E4E7102963D62C002DBA6F /* KMAnnotationFontWindowController.m in Sources */,
 				AD9527C0295294E20039D2BC /* KMPrintPageModel.swift in Sources */,
 				BBB14A6529792D6900936EDB /* KMRedactPageRangeContentView.swift in Sources */,
@@ -11193,6 +11355,7 @@
 				AD1CA3F92A05FCB60070541F /* KMAnnotationScreenViewController.swift in Sources */,
 				9F1FE4EC29406E4700E952CA /* NSBezierPath+MCAdditions.m in Sources */,
 				9F5664892988B16F00020985 /* KMTextfieldVC.swift in Sources */,
+				ADAFDA3B2AE8EEFF00F084BC /* KMAdvertisementRequestServer.swift in Sources */,
 				BBD1F77E296F9BE000343885 /* KMPageEditSettingBaseWindowController.swift in Sources */,
 				9F080B25298FCB0D00FC27DA /* KMDesignToken+Action.swift in Sources */,
 				9F81ADC829B9B12C002251F4 /* NSButton+DesignToken.swift in Sources */,
@@ -11229,6 +11392,7 @@
 				9F1FE49829406E4700E952CA /* common.c in Sources */,
 				ADBC375629CAE94700D93208 /* KMComparativeOutlineSectionCell.swift in Sources */,
 				9F0CB5442986953A00007028 /* KMURLToPDFWindowController.swift in Sources */,
+				ADAFDA322AE8E45000F084BC /* KMAdvertisementConfig.swift in Sources */,
 				ADD272D229B9CFD30032B5D6 /* KMLightNoNetworkView.swift in Sources */,
 				F3599224292CA27B000D25DE /* CPDFListViewRuntime.m in Sources */,
 				ADD1B6E12946BFD500C3FFF7 /* KMPrintChoosePageSizeSizeView.swift in Sources */,
@@ -11268,6 +11432,7 @@
 				BB897253294C3F660045787C /* KMMenuTableView.swift in Sources */,
 				BB88E45A29404752002B3655 /* KMPDFConvert.swift in Sources */,
 				BB147004299DC0D100784A6A /* OIDScopeUtilities.m in Sources */,
+				ADAFDA362AE8EE9300F084BC /* KMAdvertisementImage.swift in Sources */,
 				9F0CB4712967E63100007028 /* KMPropertiesPanelNameSubVC.swift in Sources */,
 				9F1FE4CE29406E4700E952CA /* CTTabContentsController.m in Sources */,
 				9F0CB4EF298655A800007028 /* KMDesignToken+PaddingLeft.swift in Sources */,
@@ -11304,6 +11469,7 @@
 				AD9527EC2955520C0039D2BC /* KMBaseTextFieldModel.swift in Sources */,
 				BBF38A5C294F2B760086D025 /* KMWatermarkPositionView.swift in Sources */,
 				AD5999402AD7E88600412F8B /* KMStampManager.swift in Sources */,
+				ADAFDA2D2AE8DE1B00F084BC /* KMAdvertisementCache.swift in Sources */,
 				BB7BC4DA2AD3D6B700D6BEE6 /* PDFListView+KMExtensions.swift in Sources */,
 				BB14702E299DC0D100784A6A /* OIDEndSessionRequest.m in Sources */,
 				BB146FE3299DC0D100784A6A /* GTLRDriveQuery.m in Sources */,
@@ -11336,6 +11502,7 @@
 				BB162E99295062CD0088E9D1 /* KMPageRangeTools.swift in Sources */,
 				9FD0FA3329CD947000F2AB0D /* KMOpacityPanel.swift in Sources */,
 				9FBC489D2996500300CA39D7 /* KMDocumentController.swift in Sources */,
+				ADAFDA182AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift in Sources */,
 				BB1A34AA295EA30100B80B3E /* NSBitmapImageRep_SKExtensions.m in Sources */,
 				9F0CB4A9296CF19600007028 /* KMPropertiesPanelListMenuSubVC.swift in Sources */,
 				BBB5C80929F4CEE40054F261 /* KMLinkAnnotationPropertyEmptyController.swift in Sources */,
@@ -11430,6 +11597,7 @@
 				BBD7FE042A13218F00F96075 /* KMWatermarkAdjectivePropertyBaseController.swift in Sources */,
 				ADAC0DE72AC2B04900FD4F52 /* KMNoteTypeImageView.swift in Sources */,
 				9F1FE4F229406E4700E952CA /* BackgroundGradientView.m in Sources */,
+				ADAFDA272AE8DE1B00F084BC /* KMAdvertisementModel.swift in Sources */,
 				89316824296D73CC0073EA59 /* KMSignatureAnnotationViewController.m in Sources */,
 				9F1FE4A429406E4700E952CA /* CTToolbarController.m in Sources */,
 				BBEB93ED2AD6C2AE00739573 /* KMPDFMergeFileNameTabelViewCell.swift in Sources */,

+ 36 - 36
PDF Office/PDF Master/Class/Home/ViewController/KMHomeViewController.swift

@@ -164,42 +164,42 @@ import KMAdvertisement
     }
     
     func initNetworkingData() {
-        KMAdvertisementManager.manager.fetchDataWithResponseObject { [unowned self] data, responseObject, error in
-            KMPrint("获取广告数据成功")
-            if data != nil {
-                for model in data! {
-                    guard let sectionContent = model.content else { break }
-                    if model.showType == .list {
-                        for section in sectionContent {
-                            KMPrint("list section 标题" + KMAdvertisementModelTransition.transitionLanguage(langeuage: section.sectionTitle?.language))
-                            guard let itemContent = section.content else { break }
-                            
-                            for item in itemContent {
-                                KMPrint("item 标题" + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.title?.language))
-                                KMPrint("item 图片链接" + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.imageURL?.normal?.universal))
-                                KMPrint("item 点击链接" + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.linkURL))
-                                KMPrint("item tips" + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.tips))
-                                KMPrint("item actionType" + String(Int(item.actionType.rawValue)))
-                            }
-                        }
-                    }
-                    if model.showType == .view {
-                        for section in sectionContent {
-                            KMPrint("view section 标题" + KMAdvertisementModelTransition.transitionLanguage(langeuage: section.sectionTitle?.language))
-                            guard let itemContent = section.content else { break }
-                            
-                            for item in itemContent {
-                                KMPrint("item 标题 = " + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.title?.language))
-                                KMPrint("item 图片链接 = " + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.imageURL?.normal?.universal))
-                                KMPrint("item 点击链接 = " + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.linkURL))
-                                KMPrint("item tips = " + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.tips))
-                                KMPrint("item actionType = " + String(Int(item.actionType.rawValue)))
-                            }
-                        }
-                    }
-                }
-            }
-        }
+//        KMAdvertisementManager.manager.fetchDataWithResponseObject { [unowned self] data, responseObject, error in
+//            KMPrint("获取广告数据成功")
+//            if data != nil {
+//                for model in data! {
+//                    guard let sectionContent = model.content else { break }
+//                    if model.showType == .list {
+//                        for section in sectionContent {
+//                            KMPrint("list section 标题" + KMAdvertisementModelTransition.transitionLanguage(langeuage: section.sectionTitle?.language))
+//                            guard let itemContent = section.content else { break }
+//                            
+//                            for item in itemContent {
+//                                KMPrint("item 标题" + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.title?.language))
+//                                KMPrint("item 图片链接" + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.imageURL?.normal?.universal))
+//                                KMPrint("item 点击链接" + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.linkURL))
+//                                KMPrint("item tips" + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.tips))
+//                                KMPrint("item actionType" + String(Int(item.actionType.rawValue)))
+//                            }
+//                        }
+//                    }
+//                    if model.showType == .view {
+//                        for section in sectionContent {
+//                            KMPrint("view section 标题" + KMAdvertisementModelTransition.transitionLanguage(langeuage: section.sectionTitle?.language))
+//                            guard let itemContent = section.content else { break }
+//                            
+//                            for item in itemContent {
+//                                KMPrint("item 标题 = " + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.title?.language))
+//                                KMPrint("item 图片链接 = " + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.imageURL?.normal?.universal))
+//                                KMPrint("item 点击链接 = " + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.linkURL))
+//                                KMPrint("item tips = " + KMAdvertisementModelTransition.transitionLanguage(langeuage: item.tips))
+//                                KMPrint("item actionType = " + String(Int(item.actionType.rawValue)))
+//                            }
+//                        }
+//                    }
+//                }
+//            }
+//        }
     }
     
     func setup() {

+ 20 - 0
PDF Office/PDF Master/Class/Home/ViewController/KMHomeViewController.xib

@@ -266,6 +266,23 @@ Gw
                                             <constraint firstItem="gfM-nc-QPH" firstAttribute="top" secondItem="0aC-uQ-5lW" secondAttribute="bottom" constant="8" id="m9w-w0-Rb8"/>
                                         </constraints>
                                     </customView>
+                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="eZs-02-dfp">
+                                        <rect key="frame" x="16" y="152" width="238" height="500"/>
+                                        <subviews>
+                                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="fnz-k9-XjO" customClass="KMAdvertisementTableView" customModule="PDF_Master" customModuleProvider="target">
+                                                <rect key="frame" x="0.0" y="200" width="238" height="300"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="300" id="pex-rA-Zma"/>
+                                                </constraints>
+                                            </customView>
+                                        </subviews>
+                                        <constraints>
+                                            <constraint firstItem="fnz-k9-XjO" firstAttribute="leading" secondItem="eZs-02-dfp" secondAttribute="leading" id="9nx-Kn-ay8"/>
+                                            <constraint firstAttribute="trailing" secondItem="fnz-k9-XjO" secondAttribute="trailing" id="Ea6-4t-JOh"/>
+                                            <constraint firstItem="fnz-k9-XjO" firstAttribute="top" secondItem="eZs-02-dfp" secondAttribute="top" id="SNd-w5-4mI"/>
+                                            <constraint firstAttribute="height" constant="500" id="WQL-MY-cvc"/>
+                                        </constraints>
+                                    </customView>
                                     <customView translatesAutoresizingMaskIntoConstraints="NO" id="xMk-8H-B64" customClass="KMCreatPDFView" customModule="PDF_Master" customModuleProvider="target">
                                         <rect key="frame" x="16" y="668" width="238" height="112"/>
                                         <constraints>
@@ -277,10 +294,13 @@ Gw
                                     <constraint firstAttribute="trailing" secondItem="xMk-8H-B64" secondAttribute="trailing" constant="16" id="0Y5-Y0-JAP"/>
                                     <constraint firstAttribute="bottom" secondItem="3io-Hj-Kiz" secondAttribute="bottom" id="8hH-Nz-14P"/>
                                     <constraint firstItem="xMk-8H-B64" firstAttribute="top" secondItem="2gJ-MM-ZrB" secondAttribute="top" constant="40" id="BmM-pK-ELG"/>
+                                    <constraint firstItem="eZs-02-dfp" firstAttribute="top" secondItem="xMk-8H-B64" secondAttribute="bottom" constant="16" id="BoC-48-m5e"/>
                                     <constraint firstItem="3io-Hj-Kiz" firstAttribute="top" secondItem="2gJ-MM-ZrB" secondAttribute="top" id="OUk-vQ-edJ"/>
                                     <constraint firstItem="3io-Hj-Kiz" firstAttribute="leading" secondItem="2gJ-MM-ZrB" secondAttribute="leading" id="eTW-ob-qK1"/>
                                     <constraint firstAttribute="trailing" secondItem="3io-Hj-Kiz" secondAttribute="trailing" id="kZa-Sb-BLN"/>
                                     <constraint firstItem="xMk-8H-B64" firstAttribute="leading" secondItem="2gJ-MM-ZrB" secondAttribute="leading" constant="16" id="llZ-cI-Lb3"/>
+                                    <constraint firstAttribute="trailing" secondItem="eZs-02-dfp" secondAttribute="trailing" constant="16" id="pwm-0C-e6W"/>
+                                    <constraint firstItem="eZs-02-dfp" firstAttribute="leading" secondItem="2gJ-MM-ZrB" secondAttribute="leading" constant="16" id="s35-fX-Hao"/>
                                 </constraints>
                             </view>
                         </box>

+ 43 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Cache/KMAdvertisementCache.swift

@@ -0,0 +1,43 @@
+//
+//  KMAdvertisementCache.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/25.
+//
+
+class KMAdvertisementCache: NSObject {
+    let kFilePath: NSString = NSTemporaryDirectory() + "Advertisement/advertisement.plist" as NSString
+    
+    //单例
+    public static let `default` = KMAdvertisementCache()
+    //存储
+    func saveData(data: [NSDictionary]) {
+        if (!FileManager.default.fileExists(atPath: kFilePath.deletingLastPathComponent as String)) {
+            try?FileManager.default.createDirectory(atPath: kFilePath.deletingLastPathComponent as String, withIntermediateDirectories: true, attributes: nil)
+        }
+        
+        if (!FileManager.default.fileExists(atPath: kFilePath as String)) {
+            FileManager.default.createFile(atPath: kFilePath as String, contents: nil);
+        }
+        
+        let saveData: NSArray = data as NSArray
+        let success = saveData.write(toFile: kFilePath.expandingTildeInPath as String, atomically: true)
+
+        if (success == true) {
+            print("成功 -" + (kFilePath.expandingTildeInPath as String))
+        } else {
+            print("失败 -" + (kFilePath.expandingTildeInPath as String))
+        }
+    }
+
+   //读取
+    func readData() -> [NSDictionary] {
+        print("数据地址 = " + (kFilePath.expandingTildeInPath as String))
+        let data =  NSArray.init(contentsOfFile: kFilePath.expandingTildeInPath as String)
+        if (data != nil) {
+            return data as! [NSDictionary]
+        } else {
+            return []
+        }
+    }
+}

+ 175 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Config/KMAdvertisementConfig.swift

@@ -0,0 +1,175 @@
+//
+//  KMAdvertisementConfig.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/24.
+//
+
+#if os(OSX)
+    import AppKit
+#elseif os(iOS)
+    import UIKit
+#endif
+
+//APP类型
+@objc public enum KMAdvertisementAppNameType: Int, Codable {
+    case RecordIt = 0
+    case RecordItPro = 1
+    case RecordItDMG = 2
+    case FilmageScreen = 3
+    case FilmageScreenPro = 4
+    case FilmageScreenDMG = 5
+    case FilmageEditorMac = 6
+    case FilmageEditorMacPro = 7
+    case FilmageEditorMacDMG = 8
+    case FilmageConverterMac = 9
+    case FilmageConverterMacPro = 10
+    case FilmageConverterMacDMG = 11
+    case FilmagePlayerMac = 12
+    case FilmagePlayerMacPro = 13
+    case FilmagePlayerMacDMG = 14
+    case PDFReaderProMac = 15
+    case PDFReaderProMacPro = 16
+    case PDFReaderProMacDMG = 17
+    case PDFReaderProIOS = 18
+    case PDFReaderProIOSPro = 19
+    
+    func string() -> String {
+            switch self {
+            case .RecordIt: return "RecordIt"
+            case .RecordItPro: return "RecordItPro"
+            case .RecordItDMG: return "RecordItDMG"
+            case .FilmageScreen: return "FilmageScreen"
+            case .FilmageScreenPro: return "FilmageScreenPro"
+            case .FilmageScreenDMG: return "FilmageScreenDMG"
+            case .FilmageEditorMac: return "FilmageEditorMac"
+            case .FilmageEditorMacPro: return "FilmageEditorMacPro"
+            case .FilmageEditorMacDMG: return "FilmageEditorMacDMG"
+            case .FilmageConverterMac: return "FilmageConverterMac"
+            case .FilmageConverterMacPro: return "FilmageConverterMacPro"
+            case .FilmageConverterMacDMG: return "FilmageConverterMacDMG"
+            case .FilmagePlayerMac: return "FilmagePlayerMac"
+            case .FilmagePlayerMacPro: return "FilmagePlayerMacPro"
+            case .FilmagePlayerMacDMG: return "FilmagePlayerMacDMG"
+            case .PDFReaderProMac: return "PDFReaderProMac"
+            case .PDFReaderProMacPro: return "PDFReaderProMacPro"
+            case .PDFReaderProMacDMG: return "PDFReaderProMacDMG"
+            case .PDFReaderProIOS: return "PDFReaderProIOS"
+            case .PDFReaderProIOSPro: return "PDFReaderProIOSPro"
+            }
+        }
+}
+
+//显示样式
+@objc public enum KMAdvertisementShowType: Int, Codable {
+    case unknow = 0
+    case list = 1 //列表
+    case pop = 2 //弹窗
+    case scroll = 3 //循环
+    case view = 4 //视图显示
+}
+
+//平台
+@objc public enum KMAdvertisementPlatformType: Int, Codable {
+    case unknow = 0
+    case Mac //
+    case iOS //
+}
+
+//订阅状态
+@objc public enum KMAdvertisementSubscribeType: Int, Codable {
+    case unknow = 0
+    case unsubscribed = 1 //未订阅
+    case subscribed = 2 //已订阅
+    case all = 3 //无限制
+}
+
+//点击视图后跳转选项
+@objc public enum KMAdvertisementActionType: Int, Codable {
+    case unknow = 0
+    case URL = 1 //链接
+    case comparative = 2 //比价表
+}
+
+//多语
+@objc public enum KMAdvertisementLanguageType: Int, Codable {
+    case unknow
+    case en //
+    case zhCN //
+    case zhTW //
+}
+
+@objcMembers open class KMAdvertisementConfig: NSObject {
+    var isDebug: Bool = false
+    var appName: KMAdvertisementAppNameType = .FilmageEditorMac
+    var platform: KMAdvertisementPlatformType = .Mac
+    public var subscribeType: KMAdvertisementSubscribeType = .unsubscribed
+    public var language: KMAdvertisementLanguageType = .unknow
+    
+    func activityBaseURL() -> String {
+        #if DEBUG
+        if (isDebug) {
+            // 测试 服务器
+            return "http://test-store.kdan.cn:3019"
+        } else {
+            //正式版 服务器
+            return "https://store.filmagepro.com:3018"
+        }
+        #else
+        return "https://store.filmagepro.com:3018"
+        #endif
+    }
+    
+    public func initParameters(appName: KMAdvertisementAppNameType, subscribeType:KMAdvertisementSubscribeType, platform: KMAdvertisementPlatformType) {
+        self.appName = appName
+        self.subscribeType = subscribeType
+        self.platform = platform
+    }
+}
+
+extension KMAdvertisementConfig {
+    static func adapterDark(light: AnyObject, dark: AnyObject) -> AnyObject {
+        if self.isDarkModel() {
+            return dark
+        } else {
+            return light
+        }
+    }
+    
+    static func isDarkModel() -> Bool {
+#if os(iOS)
+        if #available(iOS 12.0, *) {
+            if UITraitCollection.current.userInterfaceStyle == UIUserInterfaceStyle.dark {
+                return true
+            } else {
+                return false
+            }
+        }
+#elseif os(OSX)
+        if #available(macOS 10.14, *) {
+            let dict = UserDefaults.standard.persistentDomain(forName: UserDefaults.globalDomain) ?? nil
+            guard let dicts: Dictionary = dict else {
+//                print("不是字典类型")
+                return false
+            }
+            
+            guard let style = dicts["AppleInterfaceStyle"] as? String else {
+                print("style is not string")
+                return false
+            }
+            
+            let isDarkMode : Bool = style.compare("Dark").rawValue == 0
+            
+            if isDarkMode {
+//                print("暗黑模式\(style)")
+                return true
+            } else {
+//                print("正常模式\(style)")
+                return false
+            }
+        } else {
+            return false
+        }
+#endif
+    }
+}

+ 269 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Manager/KMAdvertisementManager.swift

@@ -0,0 +1,269 @@
+//
+//  KMAdvertisementManager.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/23.
+// 广告管理
+
+@objcMembers open class KMAdvertisementManager: NSObject {
+    //单例
+    @objc public static let manager = KMAdvertisementManager()
+    @objc public var configuration: KMAdvertisementConfig = KMAdvertisementConfig()
+    
+    /**
+     @abstract 测试模式,默认为false
+      */
+    @objc public var debug: Bool = false
+    
+    /**
+     @abstract 初始化数据
+     @param appID 产品名称
+     @param subscribeType 订阅状态,可单独在configuration设置
+     @param platform 平台
+     @return
+      */
+    @objc public func initConfig(appName: KMAdvertisementAppNameType,
+                                 subscribeType:KMAdvertisementSubscribeType,
+                                 platform: KMAdvertisementPlatformType) {
+        configuration.initParameters(appName: appName, subscribeType: subscribeType, platform: platform)
+    }
+    
+    private class InternalImplementation {
+            fileprivate var privateProperty: String = "Hidden"
+            fileprivate func internalMethod() {
+                // 实现细节
+            }
+        }
+        
+        private let internalImplementation = InternalImplementation()
+        
+        public func publicMethod() {
+            // 使用内部实现
+            internalImplementation.internalMethod()
+        }
+}
+
+extension KMAdvertisementManager {
+    //MARK: request
+    /**
+     @abstract 获取数据
+     @param data 传入参数 类型为KMAdvertisementModel
+     @return
+      */
+    @objc public func fetchData(completion: @escaping (_ data: [KMAdvertisementModel]?, _ error:Error?) -> Void) -> Void {
+        self.fetchDataWithResponseObject { data, responseObject, error in
+            if completion != nil {
+                completion(data, error)
+            }
+        }
+    }
+    
+    @objc public func fetchDataWithResponseObject(completion:@escaping (_ data: [KMAdvertisementModel]?, _ responseObject: AnyObject? , _ error:Error?) -> Void) -> Void {
+        print("开始获取数据")
+        var version: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString").debugDescription
+        if (version.count == 0) {
+            version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion").debugDescription
+            version = version.replacingOccurrences(of: ".", with: "")
+        }
+        
+//        "/api/advertise-new?app_name=%@"
+        let urlString = configuration.activityBaseURL() + "/api/advertise-new"
+        let params: [String:Any] = ["app_name": configuration.appName.string(),
+                                    "app_version": version]
+        
+        //先拿缓存数据 再请求新数据
+        let cacheData = KMAdvertisementCache.default.readData()
+        if cacheData.count != 0 {
+            self.parseData(data: cacheData, isNeedLocalComparison: false) { result in
+                if result.count != 0 {
+                    completion(result, nil, nil)
+                }
+            }
+        }
+        
+        unowned let weakSelf = self
+        KMAdvertisementRequestServer.requestServer.request(urlString: urlString, method: "GET", params: params) { task, responseObject, error in
+            print("正在获取数据")
+            if (error == nil && responseObject != nil) {
+                let array = responseObject?["list"] ?? []
+                if array != nil {
+                    //解析数据
+                    print("开始解析数据")
+                    weakSelf.parseData(data: array as! [NSDictionary], isNeedLocalComparison: true) { data in
+                        print("数据处理完毕")
+                        if data.count != 0 {
+                            completion(data, responseObject, nil)
+                        }
+                    }
+                } else {
+                    print("解析数据失败array")
+                    completion(nil, responseObject, error)
+                }
+            } else {
+                print("解析数据失败数据不存在")
+                completion(nil, responseObject, error)
+            }
+        }
+    }
+}
+
+
+extension KMAdvertisementManager {
+    //MARK: data
+    /**
+     @abstract 解析数据
+     @param data 传入参数 NSDictionary
+     @param isNeedLocalComparison 是否需要对比本地版本,如果不一样将会刷新
+     @return KMAdvertisementModel
+      */
+    public func parseData(data: [NSDictionary], isNeedLocalComparison: Bool ,completion:(_ result: [KMAdvertisementModel]) -> Void) -> Void {
+        //获取缓存数据
+        var isNeedSave = false
+        let cacheData = KMAdvertisementCache.default.readData()
+        
+        var resultArray:[KMAdvertisementModel] = []
+        for model in data {
+            if (!(cacheData.contains(model) && isNeedLocalComparison)) {
+                if (self.allowLoadData(data: model)) {
+                    let jsonString: String = (model["detail"] as? String) ?? ""
+                    let jsonData: Data = jsonString.data(using: .utf8)!
+                    
+                    let decoder = JSONDecoder()
+    //                decoder.dataDecodingStrategy = .base64
+    //                decoder.keyDecodingStrategy = .convertFromSnakeCase //带下划线命名
+
+                    decoder.nonConformingFloatDecodingStrategy = .convertFromString(positiveInfinity: "+∞", negativeInfinity: "-∞", nan: "NaN")
+    #if DEBUG
+                    //MARK: 测试使用
+                    var advertisementModel = try! decoder.decode(KMAdvertisementModel.self, from: jsonData)
+                    if (self.allowLoadContentData(data: advertisementModel)) {
+                        resultArray.append(self.allowLoadItemData(advertisementModel))
+                        isNeedSave = true
+                    }
+    #else
+    //            MARK: 此处try 使用 ? ,如果数据出问题 advertisementModel将无参数, 测试时使用!
+                    var advertisementModel = try? decoder.decode(KMAdvertisementModel.self, from: jsonData)
+                    if (advertisementModel != nil) {
+                        if (self.allowLoadContentData(data: advertisementModel!)) {
+                            resultArray.append(self.allowLoadItemData(advertisementModel!))
+                            isNeedSave = true
+                        }
+                    }
+    #endif
+                }
+            }
+        }
+        
+        if isNeedSave && isNeedLocalComparison {
+            KMAdvertisementCache.default.saveData(data: data)
+            print("已更新本地数据")
+        } else {
+            print("不需要更新本地数据")
+        }
+        
+        completion(resultArray)
+    }
+    
+    func allowLoadData(data: NSDictionary) -> Bool {
+        var result = false
+        
+        let status = (data["status"] as? Int) ?? 0
+        let app_name: String = data["app_name"] as? String ?? ""
+        
+        if (status == 1 &&
+            app_name == configuration.appName.string()) {
+            result = true
+        }
+        return result
+        
+    }
+    
+    func allowLoadContentData(data: KMAdvertisementModel) -> Bool {
+        var result = false
+        
+        let time: NSInteger = NSInteger(KMAdvertisementTimeStampConversion.getCurrentTimeInterval())!
+        let startTime: NSInteger = NSInteger(data.startTime!)!
+        let endTime: NSInteger = NSInteger(data.endTime!)!
+        let platform = configuration.platform
+        let subscribeType = configuration.subscribeType
+        let version = data.version ?? "1.0"
+        let localVersion = self.getLocalVersion()
+        let hidden = data.hidden ?? false
+        
+        if (time >= startTime &&
+            time <= endTime &&
+            platform == data.platform &&
+            self.compareVersion(nowVersion:localVersion, newVersion: version) &&
+            (subscribeType == data.subscribeType || data.subscribeType == .all) &&
+            !hidden) {
+            result = true
+        }
+        return result
+    }
+    
+    //过滤item是否显示
+    func allowLoadItemData(_ data: KMAdvertisementModel) -> KMAdvertisementModel {
+        //获取缓存数据
+        if (UserDefaults.standard.object(forKey: "KMAdvertisementShowScroll_iOS") == nil) {
+            UserDefaults.standard.set([], forKey: "KMAdvertisementShowScroll_iOS")
+        }
+        let cacheArray: [String] = UserDefaults.standard.object(forKey: "KMAdvertisementShowScroll_iOS") as! [String]
+        
+        let model = data
+        var sections: [KMAdvertisementModelSection] = []
+        for section in data.content! {
+            var items: [KMAdvertisementModelItem] = []
+            for item in section.content! {
+                let timeString = KMAdvertisementTimeStampConversion.getCurrentTimeInterval()
+                let time: NSInteger = NSInteger(timeString)!
+                let startTime: NSInteger = NSInteger(item.startTime ?? timeString)!
+                let endTime: NSInteger = NSInteger(item.endTime ?? timeString)!
+                let hidden = item.hidden ?? false
+
+//                print(hidden ? "隐藏" : "显示")
+                if (!hidden &&
+                    time >= startTime &&
+                    time <= endTime &&
+                    !cacheArray.contains(item.productID ?? "")) {
+                    items.append(item)
+                }
+            }
+            section.content = items
+            sections.append(section)
+        }
+        model.content = sections
+        return model
+    }
+    
+    //获取本地版本号
+    func getLocalVersion() -> String {
+        var localVersion = ""
+        if let v: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
+            localVersion = v
+        }
+        return localVersion
+    }
+    
+    func compareVersion(nowVersion: String, newVersion: String) -> Bool {
+        let nowArray = nowVersion.split(separator: ".")
+        let newArray = newVersion.split(separator: ".")
+        let big = nowArray.count > newArray.count ? newArray.count : nowArray.count
+        if big != 0 {
+            for index in 0...big - 1 {
+                let first = nowArray[index]
+                let second = newArray[index]
+                if Int(first)! < Int(second)!  {
+                    return true
+                }
+                if index == big - 1 {
+                    if Int(first)! <= Int(second)!  {
+                        return true
+                    }
+                }
+            }
+        } else {
+            return true
+        }
+        return false
+    }
+}

+ 92 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Model/KMAdvertisementImage.swift

@@ -0,0 +1,92 @@
+//
+//  KMAdvertisementImage.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2023/1/12.
+// 图片缓存
+
+import Foundation
+import AppKit
+
+typealias KMAdvertisementImageCompletion = (_ image: NSImage) -> Void
+class KMAdvertisementImage: NSObject {
+    static func imageWithURL(url : URL?, completion: KMAdvertisementImageCompletion?) -> NSImage {
+        var image: NSImage = NSImage()
+        if url != nil {
+            //获取缓存图片是否存在
+            let imageString: String = KMAdvertisementImageCache.fetchImageCache(url: url!)
+            if imageString != "" {
+                //存在获取本地图片
+                image = NSImage.init(contentsOfFile: imageString) ?? NSImage()
+                if completion != nil {
+                    completion!(image)
+                }
+            } else {
+                let path = KMAdvertisementImageCache.kImageCacheFilePath
+                let filePath = (path as String) + "/" + (NSString(string: NSString(string: url!.path).lastPathComponent) as String)
+                KMAdvertisementRequestServer.requestServer.downLoad(inputURL: url!, filePath: filePath) { progress in
+                    
+                } completion: { task, responseObject, error in
+                    if completion != nil {
+                        DispatchQueue.main.async {
+                            image = NSImage.init(contentsOfFile: KMAdvertisementImageCache.fetchImageCache(url: url!)) ?? NSImage()
+                            completion!(image)
+                        }
+                    }
+                }
+            }
+        }
+        return image
+    }
+}
+
+
+
+class KMAdvertisementImageCache: NSObject {
+    static let kImageCacheFilePath: NSString = NSTemporaryDirectory() + "Advertisement/ImageCache" as NSString
+    
+    static func saveImageCache(image: NSImage, name: String) {
+        if image.size.width != 0 {
+            
+            let path = KMAdvertisementImageCache.kImageCacheFilePath
+            let filePath = (path as String) + "/" + NSString(string: name).deletingPathExtension + ".png"
+            if (!FileManager.default.fileExists(atPath: path as String)) {
+                try?FileManager.default.createDirectory(atPath: path as String, withIntermediateDirectories: true, attributes: nil)
+            }
+            
+            #if os(iOS)
+            
+//            [UIImagePNGRepresentation(image) writeToFile:path + name
+//                                              atomically:YES]
+            #elseif os(OSX)
+            let cgimage = image.cgImage(forProposedRect: nil, context: nil, hints: nil)
+            if cgimage != nil {
+                let rep = NSBitmapImageRep.init(cgImage: cgimage!)
+                try?rep.representation(using: .png, properties: [:])?.write(to: URL(fileURLWithPath: filePath))
+            } else {
+                try?image.tiffRepresentation?.write(to: URL(fileURLWithPath: filePath))
+            }
+            print(path)
+            #endif
+        }
+    }
+    
+    static func fetchImageCache(url: URL) -> String {
+        if (!FileManager.default.fileExists(atPath: kImageCacheFilePath as String)) {
+            try?FileManager.default.createDirectory(atPath: kImageCacheFilePath as String, withIntermediateDirectories: true, attributes: nil)
+        }
+        
+        var string = ""
+        let name = NSString(string: url.path).lastPathComponent
+        let manager = FileManager.default
+        let contentsOfPath = try? manager.contentsOfDirectory(atPath: kImageCacheFilePath as String)
+        
+        if (contentsOfPath!.contains(name)) {
+            string = (kImageCacheFilePath as String) + "/" + name
+//            print("图片存在" + string)
+        } else {
+//            print("图片不存在" + (kImageCacheFilePath as String) + "/" + name)
+        }
+        return string
+    }
+}

+ 97 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Model/KMAdvertisementModel.swift

@@ -0,0 +1,97 @@
+//
+//  KMAdvertisementModel.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/30.
+//
+
+/**
+ 
+ */
+@objcMembers public class KMAdvertisementModel: NSObject, Codable {
+    public var appName: KMAdvertisementAppNameType = .FilmageEditorMac //产品名
+    public var platform: KMAdvertisementPlatformType = .Mac //平台
+    public var showType: KMAdvertisementShowType = .view //显示类型
+    public let startTime: String? //开始时间 时间戳
+    public let endTime: String? //结束时间 时间戳
+    public let version: String? //小于等于此版本生效
+    public let hidden: Bool? //是否显示
+    let subscribeType: KMAdvertisementSubscribeType? //是否订阅
+    public var content: [KMAdvertisementModelSection]?
+}
+
+@objcMembers public class KMAdvertisementModelSection: NSObject, Codable {
+    public let sectionTitle: KMAdvertisementModelItem.Text?
+    public var content: [KMAdvertisementModelItem]?
+}
+
+@objcMembers public class KMAdvertisementModelItem: NSObject, Codable {
+    public var productID: String?
+    public let startTime: String? //开始时间 时间戳
+    public let endTime: String? //结束时间 时间戳
+    public var hidden: Bool?
+    
+    public var index: Int?
+    public let title: Text?
+    public let imageURL: Image?
+    public let ipadImageURL: Image?
+    public let linkURL: Language?
+    public let tips: Language?
+    public let button: Text?
+    public var actionType: KMAdvertisementActionType = .URL
+    
+    public struct Text: Codable {
+        public let font: Font?
+        public let color: Color?
+        public let background: Background?
+        public let language: Language?
+    }
+    
+    public struct Font: Codable {
+        public let name: String?
+        public let size: Int?
+    }
+    
+    public struct Color: Codable {
+        let height: ColorState?
+        let normal: ColorState?
+        
+        struct ColorState: Codable {
+            public let dark: ColorInfo?
+            public let universal: ColorInfo?
+            
+            struct ColorInfo: Codable {
+                public var hex: String?
+                public var alpha: Float?
+            }
+        }
+    }
+
+    public struct Background: Codable {
+        let color: Color?
+        let layer: Layer?
+        
+        struct Layer: Codable {
+            public let cornerRadius: CGFloat?
+            public let borderWidth: CGFloat?
+            public let borderColor: Color?
+        }
+    }
+    
+    public struct Image: Codable {
+        public let height: ImageInfo?
+        public let normal: ImageInfo?
+        public let background: Background?
+    }
+    
+    public struct ImageInfo: Codable {
+        public let dark: Language?
+        public let universal: Language?
+    }
+    
+    public class Language: NSObject, Codable {
+        public let en: String?
+        public let zh_TW: String?
+        public let zh_CN: String?
+    }
+}

+ 143 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Model/KMAdvertisementModelTransition.swift

@@ -0,0 +1,143 @@
+//
+//  KMAdvertisementModelTansition.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/12/2.
+//
+import AppKit
+@objcMembers open class KMAdvertisementModelTransition: NSObject {
+    //MARK: 模型转换
+    //颜色模型转换
+    public static func transitionColor(color: KMAdvertisementModelItem.Color?, highlight:Bool) -> NSColor {
+        var result = NSColor.clear
+        guard let tempColor = color else { return result }
+        
+        if highlight {
+            let darkHex = tempColor.height?.dark?.hex
+            let darkAlpha = tempColor.height?.dark?.alpha
+            let universalHex = tempColor.height?.universal?.hex
+            let universalAlpha = tempColor.height?.universal?.alpha
+            let light = NSColor.init(hex: universalHex ?? "").withAlphaComponent(CGFloat(universalAlpha ?? 1))
+            let dark = NSColor.init(hex: darkHex ?? universalHex ?? "").withAlphaComponent(CGFloat(darkAlpha ?? universalAlpha ?? 1))
+            
+            result = KMAdvertisementConfig.adapterDark(light: light , dark: dark) as! NSColor
+        } else {
+            let darkHex = tempColor.normal?.dark?.hex
+            let darkAlpha = tempColor.normal?.dark?.alpha
+            let universalHex = tempColor.normal?.universal?.hex
+            let universalAlpha = tempColor.normal?.universal?.alpha
+            
+            let light = NSColor.init(hex: universalHex ?? "").withAlphaComponent(CGFloat(universalAlpha ?? 1))
+            let dark = NSColor.init(hex: darkHex ?? universalHex ?? "").withAlphaComponent(CGFloat(darkAlpha ?? universalAlpha ?? 1))
+            result = KMAdvertisementConfig.adapterDark(light: light, dark: dark) as! NSColor
+        }
+        
+        return result
+    }
+    
+    //图片转换
+    public static func transitionImagePath(image: KMAdvertisementModelItem.Image?, highlight:Bool) -> String {
+        var result = ""
+        guard let tempImage = image else { return result }
+        
+        if highlight {
+            if tempImage.height != nil {
+                result = transitionLanguage(langeuage: KMAdvertisementConfig.isDarkModel() ? tempImage.height!.dark : tempImage.height!.universal)
+            }
+        } else {
+            if tempImage.normal != nil {
+                result = transitionLanguage(langeuage: KMAdvertisementConfig.isDarkModel() ? tempImage.normal?.dark : tempImage.normal?.universal)
+            }
+        }
+        
+        return result
+    }
+    
+    //多语转换
+    @objc public static func transitionLanguage(langeuage: KMAdvertisementModelItem.Language?) -> String {
+        var result = ""
+//        let languageConfig = KMAdvertisementManager.manager.configuration.language
+//        if languageConfig != .unknow {
+//            if languageConfig == .en {
+//                result = langeuage?.en ?? ""
+//            } else if languageConfig == .zhCN {
+//                result = langeuage?.zh_CN ?? ""
+//            } else if languageConfig == .zhTW {
+//                result = langeuage?.zh_TW ?? ""
+//            }
+//        } else {
+//            let string = KMAdvertisementModelTransition.getLanguageType()
+//            if string == "zh-Hans-CN" {
+//                result = langeuage?.zh_CN ?? ""
+//            } else if string == "zh-Hans-TW" {
+//                result = langeuage?.zh_TW ?? ""
+//            } else {
+//                result = langeuage?.en ?? ""
+//            }
+//        }
+        return result
+    }
+    
+    public static func getLanguageType() -> String {
+#if os(iOS)
+        let def = UserDefaults.standard
+        let allLanguages: [String] = def.object(forKey: "AppleLanguages") as! [String]
+        let chooseLanguage = allLanguages.first
+        return chooseLanguage ?? "en"
+#elseif os(OSX)
+//        let locale = NSLocale.current.languageCode
+        //        let chooseLanguage = Locale.preferredLanguages[0]
+        let allLanguages: [String] = UserDefaults.standard.object(forKey: "AppleLanguages") as! [String]
+        let chooseLanguage: String = allLanguages.first ?? "en"
+        return chooseLanguage
+#endif
+    }
+}
+
+extension NSColor {
+    convenience init(hex: String) {
+        var hexString = hex
+        if hex.starts(with: "#") {
+            hexString = String(hex.dropFirst())
+        }
+        if let ui64 = UInt64(hexString, radix: 16) {
+            self.init(hex: Int(ui64))
+        } else {
+            self.init(hex: 0)  // <--- black
+        }
+        // or using ternaries as requested
+        // let hexString = hex.starts(with: "#") ? String(hex.dropFirst()) : hex
+        // let ui64 = UInt64(hexString, radix: 16)
+        // self.init(hex: ui64 != nil ? Int(ui64!) : 0)
+    }
+        
+        convenience init(hex: Int) {
+            let components = (
+                R: CGFloat((hex >> 16) & 0xff) / 255,
+                G: CGFloat((hex >> 08) & 0xff) / 255,
+                B: CGFloat((hex >> 00) & 0xff) / 255
+            )
+            self.init(red: components.R, green: components.G, blue: components.B, alpha: 1)
+        }
+
+//     func toHex(alpha: Bool = false) -> String? {
+//        guard let components = cgColor.components, components.count >= 3 else {
+//            return nil
+//        }
+//        
+//        let r = Float(components[0])
+//        let g = Float(components[1])
+//        let b = Float(components[2])
+//        var a = Float(1.0)
+//        
+//        if components.count >= 4 {
+//            a = Float(components[3])
+//        }
+//        
+//        if alpha {
+//            return String(format: "%02lX%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255), lroundf(a * 255))
+//        } else {
+//            return String(format: "%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255))
+//        }
+//    }
+}

+ 106 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Model/KMAdvertisementTimeStampConversion.swift

@@ -0,0 +1,106 @@
+//
+//  KMAdvertisementTimeStampConversion.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/29.
+//
+
+public class KMAdvertisementTimeStampConversion: NSObject {
+    
+    /**
+     @abstract 时间string转时间戳
+     @param dateString 时间戳字符串
+     @return 时间
+      */
+    static func stringDateToTimestamp(dateString: String) -> TimeInterval{
+        let formatter = DateFormatter()
+        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
+        let date = formatter.date(from: dateString)
+        let time = date!.timeIntervalSince1970 * 1000
+        return time
+    }
+
+    /**
+     @abstract 时间戳转换成时间(HH:mm)
+     @param timeString 时间戳字符串(毫秒)
+     @return 时间string
+      */
+    static func timeStringToTimeSecond(timeString: String) -> String {
+        let interval: TimeInterval = Double(timeString)! / 1000.0
+        let date: Date = Date.init(timeIntervalSince1970: interval)
+        let formatter = DateFormatter()
+        formatter.dateFormat = "HH:mm"
+        let dateString = formatter.string(from: date)
+        return dateString
+    }
+
+    /**
+     @abstract 时间string转date
+     @param string 时间
+     @return Date 时间
+      */
+    static func stringChangeToDate(string: String) -> Date {
+        let formatter = DateFormatter()
+        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
+        formatter.timeZone = NSTimeZone(abbreviation: "UTC") as TimeZone?
+        return formatter.date(from: string)!
+    }
+
+    /**
+     @abstract date转时间string
+     @param date 时间
+     @return NSString 时间
+      */
+    static func dateChangeToString(date: Date) -> String {
+        let formatter = DateFormatter()
+        formatter.dateFormat = "yyyy-MM-dd"
+        return formatter.string(from: date)
+    }
+    
+    /**
+     @abstract 获取当前的时间string
+     @return NSString 时间
+      */
+    public static func getCurrentCompainedDateString() -> String {
+        let date: Date = NSDate() as Date
+        let formatter = DateFormatter()
+        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
+        let timeString = formatter.string(from: date)
+        return timeString
+    }
+    
+    /**
+      @abstract 获取当前时间时间戳
+      */
+    public static func getCurrentTimeInterval () -> String {
+        let date = NSDate.init()
+        let timeSp: String = String(CLong(date.timeIntervalSince1970 * 1000))
+        return timeSp
+    }
+    
+    /**
+     @abstract 判断是否是24小时之内
+     @param timeStamp 时间
+     @return bool
+      */
+    static func isInaDayWithTimestamp(timeStamp: TimeInterval) -> Bool {
+        let currentTimeInterval:TimeInterval = Double(KMAdvertisementTimeStampConversion.getCurrentTimeInterval())!
+        if (currentTimeInterval - timeStamp < 24 * 60 * 60) {
+            return true
+        } else {
+            return false
+        }
+    }
+
+    /**
+     @abstract 获取当前的时间(年月日)
+     @param timeStamp 时间
+     @return bool
+      */
+    static func getCurrentTimeWithYMD() -> String{
+        let date = NSDate()
+        let formatter = DateFormatter()
+        formatter.dateFormat = "yyyy-MM-dd"
+        return formatter.string(from: date as Date)
+    }
+}

+ 167 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Request/KMAdvertisementRequestServer.swift

@@ -0,0 +1,167 @@
+//
+//  KMAdvertisementRequestServer.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/23.
+//
+
+import AFNetworking
+typealias KMAdvertisementRequestServerCompletion = (_ task: URLSessionDataTask?, _ responseObject: AnyObject?, _ error: Error?) -> Void
+class KMAdvertisementRequestServer {
+    var sessionManager: AFHTTPSessionManager!
+    static let requestServer = KMAdvertisementRequestServer()
+    
+    init() {
+        let configuration: URLSessionConfiguration = URLSessionConfiguration.default
+        sessionManager = AFHTTPSessionManager.init(sessionConfiguration: configuration)
+        sessionManager.securityPolicy = AFSecurityPolicy.default()
+    }
+    
+    func request(urlString: String,
+                 method:String,
+                 params: Dictionary<String, Any>?,
+                 completion: @escaping KMAdvertisementRequestServerCompletion) -> Void {
+        self.request(urlString: urlString,
+                     method: method,
+                     params: params,
+                     requestSerializer: nil,
+                     completion: completion)
+    }
+    
+    func request(urlString: String,
+                 method:String,
+                 params: Dictionary<String, Any>?,
+                 requestSerializer: ((_ requestSerializer:AFHTTPRequestSerializer) -> Void)?,
+                 completion: @escaping KMAdvertisementRequestServerCompletion) -> Void {
+        self.request(urlString: urlString,
+                     method: method,
+                     params: params,
+                     requestSerializer: requestSerializer,
+                     body: nil,
+                     completion: completion)
+    }
+    
+    func request(urlString: String,
+                 method:String,
+                 params: Dictionary<String, Any>?,
+                 requestSerializer: ((_ requestSerializer:AFHTTPRequestSerializer) -> Void)?,
+                 body: ((_ formData:AFMultipartFormData) -> Void)?,
+                 completion: @escaping KMAdvertisementRequestServerCompletion) -> Void {
+        //每次请求需要重新创建
+        sessionManager.requestSerializer = AFJSONRequestSerializer()
+        sessionManager.responseSerializer = AFJSONResponseSerializer()
+        sessionManager.responseSerializer.acceptableContentTypes = ["application/json","text/html","text/json","text/javascript","text/plain","image/gif"]
+        sessionManager.requestSerializer.timeoutInterval = 20
+        if (requestSerializer != nil) {
+            requestSerializer!(sessionManager.requestSerializer);
+        }
+        
+        if (method == "POST") {
+            if (body != nil) {
+                sessionManager.post(urlString, parameters: params, headers: nil) { formData in
+                    body!(formData)
+                } progress: { progress in
+                    
+                } success: { task, responseObject in
+                    let responseObject = responseObject as AnyObject
+                    completion(task,responseObject,nil);
+                } failure: { task, error in
+                    completion(task,nil,error);
+                }
+            } else {
+                sessionManager.post(urlString, parameters: params, headers: nil) { progress in
+                
+                } success: { task, responseObject in
+                    let responseObject = responseObject as AnyObject
+                    completion(task,responseObject,nil)
+                } failure: { task, error in
+                    completion(task,nil,error)
+                }
+
+            }
+        } else if (method == "GET") {
+            sessionManager.get(urlString, parameters: params, headers: nil) { progress in
+                
+            } success: { task, responseObject in
+                let responseObject = responseObject as AnyObject
+                completion(task,responseObject,nil)
+            } failure: { task, error in
+                completion(task,nil,error)
+            }
+        }
+    }
+    
+    /**
+     下载
+     */
+    func downLoad(inputURL: URL,
+                  filePath: String,
+                  progress: @escaping(_ progress: Progress) -> Void,
+                  completion: @escaping KMAdvertisementRequestServerCompletion) {
+        let request: URLRequest = URLRequest.init(url: inputURL)
+        self.sessionManager.requestSerializer.timeoutInterval = 100.0
+        let downloadTask = self.sessionManager.downloadTask(with: request) { resultProgress in
+            progress(resultProgress)
+        } destination: { url, response in
+            return NSURL(fileURLWithPath: filePath) as URL
+        } completionHandler: { resultResponse, resultUrl, error in
+            completion(nil, resultResponse, error)
+        }
+        downloadTask.resume()
+
+
+//        /* 下载地址 */
+//        NSURL *url = [NSURL URLWithString:requestURL];
+//        NSURLRequest *request = [NSURLRequest requestWithURL:url];
+//        /* 下载路径 */
+//        NSString *downFilePath = [NSString stringWithFormat:@"%@/%@", [self setPathOfDocumentsByFileCreated:created fileName:fileName], fileName];
+//        self.downFilePath = downFilePath;
+//
+//        /* 开始请求下载 */
+//        self.downloadTask = [_sessionManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
+//            float p = downloadProgress.fractionCompleted * 100;
+//            if (progress) {
+//                progress(p);
+//            }
+//            NSLog(@"下载进度:%.0f%", downloadProgress.fractionCompleted * 100);
+//        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
+//            dispatch_async(dispatch_get_main_queue(), ^{
+//                //如果需要进行UI操作,需要获取主线程进行操作
+//            });
+//            /* 设定下载到的位置 */
+//            return [NSURL fileURLWithPath:downFilePath];
+//
+//        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
+//            NSLog(@"下载完成");
+//            if (error) {
+//                if (failure) {
+//                    failure(error);
+//                }
+//                [weakSelf removeDownLoadFile];
+//            } else {
+//                if (success) {
+//                    success(downFilePath,[weakSelf setPathOfDocumentsByFileCreated:created fileName:fileName]);
+//                }
+//            }
+//        }];
+//        [self.downloadTask resume];
+    }
+    
+    /*
+     status
+     AFNetworkReachabilityStatusUnknown          = -1, 不知道监测的是什么
+     AFNetworkReachabilityStatusNotReachable     = 0,  没有检测到网络
+     AFNetworkReachabilityStatusReachableViaWWAN = 1,  蜂窝网
+     AFNetworkReachabilityStatusReachableViaWiFi = 2,  WIFI
+     */
+    func reachabilityStatusChange(block: @escaping(AFNetworkReachabilityStatus) ->Void) {
+        // 1.创建网络监测单例
+        let manager = AFNetworkReachabilityManager.shared()
+        manager.setReachabilityStatusChange({ status in
+            // 2.实现网络监测的回调
+            block(status)
+        })
+        // 3.开始监测
+        manager.startMonitoring()
+    }
+}

+ 46 - 0
PDF Office/PDF Master/Class/KMAdvertisement/View/Cell/KMAdvertisementCollectionHeadView.swift

@@ -0,0 +1,46 @@
+//
+//  KMAdvertisementCollectionHeadView.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/28.
+//
+
+#if os(OSX)
+    import AppKit
+#elseif os(iOS)
+    import UIKit
+#endif
+class KMAdvertisementCollectionHeadView: NSView {
+
+    lazy var titleTextField: NSTextField? = {
+        for view in self.subviews {
+            if view is NSTextField {
+                return view as? NSTextField
+            }
+        }
+        return nil
+    }()
+    
+    var model: KMAdvertisementModelSection! {
+        didSet {
+            self.reloadData()
+        }
+    }
+    
+    func reloadData() {
+        if model?.sectionTitle?.language != nil {
+            self.titleTextField?.stringValue = KMAdvertisementModelTransition.transitionLanguage(langeuage: (model?.sectionTitle?.language)!)
+        }
+        
+        if model.sectionTitle?.color != nil {
+            self.titleTextField?.textColor = KMAdvertisementModelTransition.transitionColor(color: (model.sectionTitle?.color)!, highlight: false)
+        }
+    }
+    
+    override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+
+        // Drawing code here.
+    }
+    
+}

+ 32 - 0
PDF Office/PDF Master/Class/KMAdvertisement/View/Cell/KMAdvertisementCollectionHeadView.xib

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner"/>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="c22-O7-iKe" customClass="KMAdvertisementCollectionHeadView" customModule="KMAdvertisement" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="480" height="30"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="DuE-Mw-GiV">
+                    <rect key="frame" x="6" y="7" width="37" height="16"/>
+                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="KZj-T6-HnW">
+                        <font key="font" usesAppearanceFont="YES"/>
+                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                    </textFieldCell>
+                </textField>
+            </subviews>
+            <constraints>
+                <constraint firstItem="DuE-Mw-GiV" firstAttribute="centerY" secondItem="c22-O7-iKe" secondAttribute="centerY" id="b12-fX-rby"/>
+                <constraint firstItem="DuE-Mw-GiV" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="8" id="rGK-BD-UB7"/>
+            </constraints>
+            <point key="canvasLocation" x="0.0" y="172"/>
+        </customView>
+    </objects>
+</document>

+ 64 - 0
PDF Office/PDF Master/Class/KMAdvertisement/View/Cell/KMAdvertisementCollectionViewItem.swift

@@ -0,0 +1,64 @@
+//
+//  KMAdvertisementCollectionViewItem.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/28.
+//
+
+import Cocoa
+class KMAdvertisementCollectionViewItem: NSCollectionViewItem {
+    @IBOutlet weak var iconImageView: NSImageView!
+    @IBOutlet weak var titleLabel: NSTextField!
+    
+    @IBOutlet weak var contentView: NSView!
+    var model: KMAdvertisementModelItem! {
+        didSet {
+            self.reloadData()
+        }
+    }
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        // Do view setup here.
+        self.view.addTrackingRect(self.view.bounds, owner: self, userData: nil, assumeInside: false)
+        self.contentView.wantsLayer = true
+        self.contentView.layer?.masksToBounds = true
+    }
+    
+    func reloadData() {
+        self.titleLabel.stringValue = KMAdvertisementModelTransition.transitionLanguage(langeuage: model?.title?.language)
+        self.titleLabel.font = NSFont.init(name: model?.title?.font?.name ?? "AppleSystemUIFont", size: CGFloat(model?.title?.font?.size ?? 13))
+        self.contentView.toolTip = KMAdvertisementModelTransition.transitionLanguage(langeuage: model?.tips)
+        self.contentView.layer?.cornerRadius = model.title?.background?.layer?.cornerRadius ?? 0
+        self.updateColor(false)
+    }
+    
+    func updateColor(_ highlight: Bool) {
+        
+        if model.title?.color != nil {
+            self.titleLabel.textColor = KMAdvertisementModelTransition.transitionColor(color: (model.title?.color), highlight: highlight)
+        }
+        
+        if model.title?.background?.color != nil {
+            self.contentView.layer?.backgroundColor = KMAdvertisementModelTransition.transitionColor(color: (model.title?.background?.color)!, highlight: highlight).cgColor
+        }
+        
+        if model.imageURL != nil {
+            weak var weakSelf = self
+            let url = URL(string: KMAdvertisementModelTransition.transitionImagePath(image: model.imageURL!, highlight: highlight))
+            self.iconImageView.image = KMAdvertisementImage.imageWithURL(url: url, completion: { image in
+                if weakSelf != nil {
+                    weakSelf!.iconImageView.image = image
+                }
+            })
+        }
+    }
+    
+    override func mouseEntered(with event: NSEvent) {
+        self.updateColor(true)
+    }
+
+    override func mouseExited(with event: NSEvent) {
+        self.updateColor(false)
+    }
+}

+ 59 - 0
PDF Office/PDF Master/Class/KMAdvertisement/View/Cell/KMAdvertisementCollectionViewItem.xib

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMAdvertisementCollectionViewItem" customModule="KMAdvertisement">
+            <connections>
+                <outlet property="contentView" destination="LdM-b2-48C" id="hxf-ZH-gmW"/>
+                <outlet property="iconImageView" destination="EPJ-sc-6wa" id="qq0-MW-YTG"/>
+                <outlet property="titleLabel" destination="8KY-8V-DxN" id="tt2-Pa-lKm"/>
+                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="Hz6-mo-xeY">
+            <rect key="frame" x="0.0" y="0.0" width="480" height="40"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="LdM-b2-48C">
+                    <rect key="frame" x="8" y="0.0" width="464" height="40"/>
+                    <subviews>
+                        <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="EPJ-sc-6wa">
+                            <rect key="frame" x="8" y="11" width="18" height="18"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="18" id="Ywl-Eq-mjQ"/>
+                                <constraint firstAttribute="height" constant="18" id="hZR-Bt-Rqf"/>
+                            </constraints>
+                            <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" id="3Et-Pz-ChQ"/>
+                        </imageView>
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8KY-8V-DxN">
+                            <rect key="frame" x="32" y="12" width="37" height="16"/>
+                            <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="Ikm-0K-43v">
+                                <font key="font" metaFont="system"/>
+                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="8KY-8V-DxN" firstAttribute="centerY" secondItem="LdM-b2-48C" secondAttribute="centerY" id="QhX-B6-0Gz"/>
+                        <constraint firstItem="EPJ-sc-6wa" firstAttribute="centerY" secondItem="LdM-b2-48C" secondAttribute="centerY" id="S3d-gc-JcD"/>
+                        <constraint firstItem="8KY-8V-DxN" firstAttribute="leading" secondItem="EPJ-sc-6wa" secondAttribute="trailing" constant="8" id="WvN-xe-2DQ"/>
+                        <constraint firstItem="EPJ-sc-6wa" firstAttribute="leading" secondItem="LdM-b2-48C" secondAttribute="leading" constant="8" id="ySs-Bg-GIy"/>
+                    </constraints>
+                </customView>
+            </subviews>
+            <constraints>
+                <constraint firstItem="LdM-b2-48C" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="8" id="3Z0-5E-Ft2"/>
+                <constraint firstAttribute="trailing" secondItem="LdM-b2-48C" secondAttribute="trailing" constant="8" id="QxU-Q6-tXm"/>
+                <constraint firstAttribute="bottom" secondItem="LdM-b2-48C" secondAttribute="bottom" id="Yfe-zv-dSm"/>
+                <constraint firstItem="LdM-b2-48C" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="vKN-hS-h44"/>
+            </constraints>
+            <point key="canvasLocation" x="157" y="45"/>
+        </customView>
+    </objects>
+</document>

+ 161 - 0
PDF Office/PDF Master/Class/KMAdvertisement/View/KMAdvertisementTableView.swift

@@ -0,0 +1,161 @@
+//
+//  KMAdvertisementTableView.swift
+//  KMAdvertisement
+//
+//  Created by lizhe on 2022/11/28.
+//
+
+#if os(OSX)
+    import AppKit
+#elseif os(iOS)
+    import UIKit
+#endif
+
+typealias KMAdvertisementTableViewDidSelect = (_ view: KMAdvertisementTableView, _ item: KMAdvertisementModelItem) -> Void
+@objcMembers open class KMAdvertisementTableView: NSView {
+
+    @IBOutlet var contentView: NSView!
+    
+    @IBOutlet weak var collectionView: NSCollectionView!
+
+    
+    var didSelect: KMAdvertisementTableViewDidSelect?
+    /**
+      @abstract 外部传入数据
+      @param inputData 文件路劲
+      */
+    open var inputData: KMAdvertisementModel! {
+        didSet {
+            
+        }
+    }
+
+    //内部使用数据
+    fileprivate var data: [KMAdvertisementModelSection]?
+
+    open override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+
+        // Drawing code here.
+    }
+    
+    convenience init (data: KMAdvertisementModel, superView: NSView) {
+        self.init(frame: superView.bounds)
+        superView.addSubview(self)
+        self.autoresizingMask = [.height , .width]
+//        self.translatesAutoresizingMaskIntoConstraints = false
+//        NSLayoutConstraint.activate([
+//            self.topAnchor.constraint(equalTo: topAnchor),
+//            self.leftAnchor.constraint(equalTo: leftAnchor),
+//            self.rightAnchor.constraint(equalTo: rightAnchor),
+//            self.bottomAnchor.constraint(equalTo: bottomAnchor)])
+//        self.updateConstraintsForSubtreeIfNeeded()
+    }
+    
+    public override init(frame frameRect: NSRect) {
+        super.init(frame: frameRect)
+        initContentView()
+        setup()
+    }
+    
+    // MARK: 初始化
+    public required init?(coder decoder: NSCoder) {
+        super.init(coder: decoder)
+        initContentView()
+        setup()
+    }
+
+    private func initContentView() {
+        //绑定xib
+        let resource = NSNib(nibNamed: String(describing: self.classForCoder.self),
+                             bundle: Bundle(for: self.classForCoder.self))!
+        resource.instantiate(withOwner: self, topLevelObjects: nil)
+        addSubview(contentView)
+        contentView.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            contentView.topAnchor.constraint(equalTo: topAnchor),
+            contentView.leftAnchor.constraint(equalTo: leftAnchor),
+            contentView.rightAnchor.constraint(equalTo: rightAnchor),
+            contentView.bottomAnchor.constraint(equalTo: bottomAnchor)])
+        contentView.updateConstraintsForSubtreeIfNeeded()
+    }
+    
+    func setup() {
+        //设置代理
+        self.collectionView.delegate = self
+        self.collectionView.dataSource = self
+        //是否可选中
+        self.collectionView.isSelectable = true
+        //注册cell
+        self.collectionView.register(KMAdvertisementCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMAdvertisementCollectionViewItem"))
+    }
+}
+
+extension KMAdvertisementTableView: NSCollectionViewDelegate {
+    //当item被选中
+    public func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
+        print("点击")
+        let view = collectionView.item(at: indexPaths.first!) as! KMAdvertisementCollectionViewItem
+        
+        var content = view.model
+        
+        guard let callBack = didSelect else { return }
+        
+        content?.index = indexPaths.first?.item
+        callBack(self, content!)
+    }
+    
+   //当item取消选中
+    public func collectionView(_ collectionView: NSCollectionView, didDeselectItemsAt indexPaths: Set<IndexPath>) {
+        let view = collectionView.item(at: indexPaths.first!) as! KMAdvertisementCollectionViewItem
+    }
+}
+
+extension KMAdvertisementTableView: NSCollectionViewDataSource {
+    public func numberOfSections(in collectionView: NSCollectionView) -> Int {
+        return self.data?.count ?? 0
+    }
+    
+    public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
+        let model: KMAdvertisementModelSection = (self.data?[section])!
+        return model.content!.count
+    }
+    
+    //返回对应的item自定义个体
+    public func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
+        let view = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMAdvertisementCollectionViewItem"), for: indexPath) as! KMAdvertisementCollectionViewItem
+        
+        let model = self.data?[indexPath.section]
+        view.model = model?.content![indexPath.item]
+        return view
+    }
+    
+    public func collectionView(_ collectionView: NSCollectionView, viewForSupplementaryElementOfKind kind: NSCollectionView.SupplementaryElementKind, at indexPath: IndexPath) -> NSView {
+        var nibName: String?
+        if kind == NSCollectionView.elementKindSectionHeader {
+            nibName = "KMAdvertisementCollectionHeadView"
+        }
+        
+        let view = collectionView.makeSupplementaryView(ofKind: kind, withIdentifier: NSUserInterfaceItemIdentifier(rawValue: nibName!), for: indexPath)
+        if let view = view as? KMAdvertisementCollectionHeadView {
+            let model = self.data?[indexPath.section]
+            view.model = model
+        }
+        return view
+    }
+}
+
+extension KMAdvertisementTableView: NSCollectionViewDelegateFlowLayout {
+    
+    public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
+        return NSSize(width: self.contentView.bounds.width, height: 32)
+    }
+    
+    public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> NSSize {
+        return NSSize(width: 0, height: 30)
+    }
+    
+    public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
+        return 4
+    }
+}

+ 57 - 0
PDF Office/PDF Master/Class/KMAdvertisement/View/KMAdvertisementTableView.xib

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMAdvertisementTableView" customModule="KMAdvertisement" customModuleProvider="target">
+            <connections>
+                <outlet property="collectionView" destination="DM1-E5-H8J" id="npq-W6-KFs"/>
+                <outlet property="contentView" destination="c22-O7-iKe" id="PMK-sn-xgD"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="c22-O7-iKe">
+            <rect key="frame" x="0.0" y="0.0" width="549" height="364"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <scrollView wantsLayer="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UFo-Fd-Vqk">
+                    <rect key="frame" x="0.0" y="0.0" width="549" height="364"/>
+                    <clipView key="contentView" drawsBackground="NO" id="M51-ZI-aP5">
+                        <rect key="frame" x="0.0" y="0.0" width="549" height="364"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <collectionView id="DM1-E5-H8J">
+                                <rect key="frame" x="0.0" y="0.0" width="549" height="364"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
+                                <collectionViewFlowLayout key="collectionViewLayout" id="QQ0-er-OSn">
+                                    <size key="itemSize" width="50" height="50"/>
+                                </collectionViewFlowLayout>
+                                <color key="primaryBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            </collectionView>
+                        </subviews>
+                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    </clipView>
+                    <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="PAQ-UO-Nz6">
+                        <rect key="frame" x="-100" y="-100" width="233" height="15"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="BXa-fT-rRG">
+                        <rect key="frame" x="234" y="1" width="15" height="143"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                </scrollView>
+            </subviews>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="UFo-Fd-Vqk" secondAttribute="bottom" id="KWL-Zf-KFW"/>
+                <constraint firstItem="UFo-Fd-Vqk" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" id="ShF-i8-p4g"/>
+                <constraint firstItem="UFo-Fd-Vqk" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" id="oVj-wf-0sg"/>
+                <constraint firstAttribute="trailing" secondItem="UFo-Fd-Vqk" secondAttribute="trailing" id="v5c-3v-n9k"/>
+            </constraints>
+            <point key="canvasLocation" x="44" y="184"/>
+        </customView>
+    </objects>
+</document>