Compare commits

...
Sign in to create a new pull request.

17 commits

Author SHA1 Message Date
QuentinArguillere
d53bf09702 After the SDK changes to IOS audio routes, we now update bluetooth availability flag in “onAudioDevicesListUpdated” callback, and we manually set the route to bluetooth when starting calls with an available bluetooth device (this allows the overriding, from the App, of the core.defaultOutputDevice settings for the SDK) 2022-01-03 16:50:29 +01:00
QuentinArguillere
eb6cf542fb Do not change identity address to “sips” when transport is pls 2021-10-08 11:30:03 +02:00
Danmei Chen
fea93b82e9 beta 4.5.1(4) 2021-10-07 15:16:11 +02:00
Danmei Chen
7c08c38829 get image from either download dir or cache dir 2021-10-07 15:10:08 +02:00
Danmei Chen
b6587a2bb9 use download dir 2021-10-04 12:04:10 +02:00
Danmei Chen
2a7b6c4a7f Revert "migration all images from cacheDirectory to imagesDirectory, to avoid automaic clear of cache"
This reverts commit 88e807c529.
2021-10-04 12:04:01 +02:00
Danmei Chen
3c1bffaf8a Application extensions and any libraries they link to must be built with the build setting set to YES 2021-09-30 11:37:58 +02:00
QuentinArguillere
c2849ddb56 Add an equivalence between “sips:” uri and TLS transport in the account settings 2021-09-27 09:10:38 +02:00
Christophe Deschamps
f64de9d8de Merge branch 'release/4.5' of gitlab.linphone.org:BC/public/linphone-iphone into release/4.5 2021-09-16 10:28:53 +02:00
Christophe Deschamps
e8a348ada2 - Notify LinphoneCallUpdate on call back thread
- Fix "no more call" detection to dismiss call views within call call back itself.
2021-09-16 10:27:52 +02:00
QuentinArguillere
ca9e321a68 Fix potential crash, and hide the account link menu if there is no account 2021-09-15 17:35:30 +02:00
Christophe Deschamps
b9f8a7f025 - Use the new conference call API
- Displays participants when joining a conference call as a guest
2021-09-15 16:43:33 +02:00
Simon Morlat
98ac45f92a Show a dialog to requet the user to grant the local network permission.
This is required for ICE to operate correctly.
If not granted, SDK 5.0.16 will automatically disable ICE.
2021-09-02 15:46:36 +02:00
Danmei Chen
09d0867807 fix text display error with video in the same chat 2021-08-03 08:42:22 +00:00
Danmei Chen
8eda10d770 fix crash : try to use the core because of post event , though the core is already destroyed 2021-07-30 15:03:55 +02:00
QuentinArguillere
a3f63cc70c Update linphone.xcodeprojet to 4.5.0 (1) 2021-07-08 16:57:11 +02:00
QuentinArguillere
e390fbeac2 Update changelog and Podfile for 4.5.0 2021-07-08 16:56:03 +02:00
28 changed files with 984 additions and 651 deletions

View file

@ -3,13 +3,32 @@ All notable changes to this project will be documented in this file.
Group changes to describe their impact on the project, as follows: Group changes to describe their impact on the project, as follows:
Added for new features. Added for new features.
Changed for changes in existing functionality. Changed for changes in existing functionality.
Deprecated for once-stable features removed in upcoming releases. Deprecated for once-stable features removed in upcoming releases.
Removed for deprecated features removed in this release. Removed for deprecated features removed in this release.
Fixed for any bug fixes. Fixed for any bug fixes.
Security to invite users to upgrade in case of vulnerabilities. Security to invite users to upgrade in case of vulnerabilities.
## [4.5.0] - 2021-07-08
### Added
- Add option to enable VFS
- Ephemeral messages (beta)
### Changed
- Updating SDK to 5.0 version
- Using linphone SDK 5.0 API to better handle audio route
- Replaced all notions of "Proxy configs" with "Accounts" from the 5.0 SDK
- Removed most of the code related to remote and VOIP Push Notification receptions, now handled in the SDK
- No longer pause all calls when receiving a new call.
- No longer switch to speaker during video call if another output device (bluetooth headset) is already connected
- When answering a video call while the phone is locked, send the "No camera available" image until the video is enabled through the CallKit button
- Chat messages containing both text and file are now displayed in the same chat bubble
### Fixed
- Fix several memory leaks
- Various crashs and issues.
- When the App is started through a Push Notification, properly redirect the view to the corresponding chat rather than going to the home page
## [4.4.0] - 2021-03-30 ## [4.4.0] - 2021-03-30
@ -66,7 +85,7 @@ Group changes to describe their impact on the project, as follows:
### Fixed ### Fixed
- Automatically downloaded images are copied when shared in a chat room. - Automatically downloaded images are copied when shared in a chat room.
- Some UI errors from ios 13. - Some UI errors from ios 13.
## [4.1.0] - 2019-05-06 ## [4.1.0] - 2019-05-06
### Added ### Added

View file

@ -68,7 +68,7 @@
assistant_activate_phone_number_link); assistant_activate_phone_number_link);
LinphoneAccount *acc = linphone_core_get_default_account(LC); LinphoneAccount *acc = linphone_core_get_default_account(LC);
LinphoneAccountParams const *accParams = linphone_account_get_params(acc); LinphoneAccountParams const *accParams = (acc) ? linphone_account_get_params(acc) : NULL;
if (acc && if (acc &&
strcmp([LinphoneManager.instance lpConfigStringForKey:@"domain_name" strcmp([LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app" inSection:@"app"

View file

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/> <device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
@ -99,10 +100,10 @@
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<tableView clipsSubviews="YES" tag="4" contentMode="scaleToFill" fixedFrame="YES" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" style="grouped" allowsSelection="NO" rowHeight="50" sectionHeaderHeight="1" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="vgc-Mn-pga" userLabel="conferenceCallsTableView"> <tableView clipsSubviews="YES" tag="4" contentMode="scaleToFill" fixedFrame="YES" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" style="grouped" allowsSelection="NO" rowHeight="60" sectionHeaderHeight="1" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="vgc-Mn-pga" userLabel="conferenceCallsTableView">
<rect key="frame" x="0.0" y="66" width="375" height="431"/> <rect key="frame" x="0.0" y="66" width="375" height="431"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="separatorColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/> <color key="separatorColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<connections> <connections>
<outlet property="dataSource" destination="sif-q0-7oE" id="Oes-Ng-FKF"/> <outlet property="dataSource" destination="sif-q0-7oE" id="Oes-Ng-FKF"/>
@ -121,7 +122,7 @@
<state key="highlighted" image="pause_big_over_selected.png"/> <state key="highlighted" image="pause_big_over_selected.png"/>
</button> </button>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view> </view>
<view clearsContextBeforeDrawing="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9" userLabel="callView"> <view clearsContextBeforeDrawing="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9" userLabel="callView">
<rect key="frame" x="0.0" y="0.0" width="375" height="625"/> <rect key="frame" x="0.0" y="0.0" width="375" height="625"/>
@ -198,7 +199,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view> </view>
<view hidden="YES" alpha="0.80000000000000004" tag="16" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0MR-ml-8RY" userLabel="pausedByRemoteView"> <view hidden="YES" alpha="0.80000000000000004" tag="16" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0MR-ml-8RY" userLabel="pausedByRemoteView">
<rect key="frame" x="0.0" y="66" width="375" height="559"/> <rect key="frame" x="0.0" y="66" width="375" height="559"/>
@ -238,7 +239,7 @@
</connections> </connections>
</button> </button>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view> </view>
<view hidden="YES" tag="20" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aqL-q2-eR2" userLabel="noActiveCallView"> <view hidden="YES" tag="20" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aqL-q2-eR2" userLabel="noActiveCallView">
<rect key="frame" x="0.0" y="0.0" width="375" height="499"/> <rect key="frame" x="0.0" y="0.0" width="375" height="499"/>
@ -395,7 +396,7 @@
<state key="highlighted" image="numpad_hash_over.png" backgroundImage="numpad_over_background.png"/> <state key="highlighted" image="numpad_hash_over.png" backgroundImage="numpad_over_background.png"/>
</button> </button>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view> </view>
<view hidden="YES" tag="37" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qcR-Qb-Bst" userLabel="routesView"> <view hidden="YES" tag="37" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qcR-Qb-Bst" userLabel="routesView">
<rect key="frame" x="188" y="301" width="94" height="198"/> <rect key="frame" x="188" y="301" width="94" height="198"/>
@ -701,11 +702,11 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView> </activityIndicatorView>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<gestureRecognizers/> <gestureRecognizers/>
</view> </view>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view> </view>
</subviews> </subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -730,7 +731,7 @@
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<tableView clipsSubviews="YES" tag="4" contentMode="scaleToFill" fixedFrame="YES" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" style="grouped" allowsSelection="NO" rowHeight="50" sectionHeaderHeight="1" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="7Ih-sO-8Uo" userLabel="conferenceCallsTableView"> <tableView clipsSubviews="YES" tag="4" contentMode="scaleToFill" fixedFrame="YES" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" style="grouped" allowsSelection="NO" rowHeight="60" sectionHeaderHeight="1" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="7Ih-sO-8Uo" userLabel="conferenceCallsTableView">
<rect key="frame" x="0.0" y="66" width="375" height="440"/> <rect key="frame" x="0.0" y="66" width="375" height="440"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
@ -1161,7 +1162,7 @@
<state key="normal" image="button:GQK-F8-oLr:image"> <state key="normal" image="button:GQK-F8-oLr:image">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state> </state>
<state key="disabled" image="59BB6A35-C469-4FDF-86F9-4404B36D4F19"/> <state key="disabled" image="0312E5E8-BBE7-4B02-9842-3D4CB1F3B042"/>
<state key="highlighted" backgroundImage="color_E.png"/> <state key="highlighted" backgroundImage="color_E.png"/>
<connections> <connections>
<action selector="onRecordClick:" destination="-1" eventType="touchUpInside" id="IFO-tT-oog"/> <action selector="onRecordClick:" destination="-1" eventType="touchUpInside" id="IFO-tT-oog"/>
@ -1343,215 +1344,218 @@
</view> </view>
</objects> </objects>
<resources> <resources>
<image name="59BB6A35-C469-4FDF-86F9-4404B36D4F19" width="33" height="33"> <image name="0312E5E8-BBE7-4B02-9842-3D4CB1F3B042" width="33" height="33">
<mutableData key="keyedArchiveRepresentation"> <mutableData key="keyedArchiveRepresentation">
YnBsaXN0MDDUAQIDBAUGVVZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK8QEgcI YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05T
ExQZHh8jJCsuMTtDR0tPUlUkbnVsbNUJCgsMDQ4PEBESVk5TU2l6ZVYkY2xhc3NcTlNJbWFnZUZsYWdz S2V5ZWRBcmNoaXZlctEICVRyb290gAGvEBELDBkaHxQkKSoxNDdBSUpOUVUkbnVsbNYNDg8QERITFBUW
Vk5TUmVwc1dOU0NvbG9ygAKAERIgwAAAgAOAC1h7MzMsIDMzfdIVChYYWk5TLm9iamVjdHOhF4AEgArS FxhWTlNTaXplXk5TUmVzaXppbmdNb2RlViRjbGFzc1xOU0ltYWdlRmxhZ3NWTlNSZXBzV05TQ29sb3KA
FQoaHaIbHIAFgAaACRAA0iAKISJfEBROU1RJRkZSZXByZXNlbnRhdGlvboAHgAhPERm6TU0AKgAAEQwA AhAAgBASIMAAAIADgAtYezMzLCAzM33SGw8cHlpOUy5vYmplY3RzoR2ABIAK0hsPICOiISKABYAGgAnT
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQMDAxUG DyUmJygUXxAUTlNUSUZGUmVwcmVzZW50YXRpb25fEBlOU0ludGVybmFsTGF5b3V0RGlyZWN0aW9ugAiA
BgYmBgYGIgICAgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA B08RGbpNTQAqAAARDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAABAwMDFQYGBiYGBgYiAgICDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAACBgYGIQkJCTYJCQkxCQkJMwkJCTMDAwMUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAIGBgYhCQkJNgkJCTEJCQkzCQkJMwMDAxQAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAADAwMVCgoKNgUFBSABAQEIAgICDAgICCsJCQkxAQEBBwAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAxUKCgo2BQUFIAEBAQgCAgIMCAgIKwkJCTEBAQEHAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAMDAxQA
AAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAGBgYjCAgIMAAAAAUAAAAAAAAAAAICAhEKCgo2AgICEgAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAgICDgoKCjUHBwcuAwMDEgAAAAEAAAAAAAAAAAAAAAAGBgYhCAgIMQEBAQcAAAAAAAAAAAMDAxQK AAAAAAAAAAAEAwMDFAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAYGBiMICAgwAAAABQAAAAAAAAAAAgIC
Cgo2AgICEAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA EQoKCjYCAgISAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAwMDDwkJCTIJCQk1CQkJNAQEBBkAAAAAAAAAAAAAAAAFBQUbCgoKNwUFBR8A AAAAAAAAAAAAAAAAAAAAAAACAgIOCgoKNQcHBy4DAwMSAAAAAQAAAAAAAAAAAAAAAAYGBiEICAgxAQEB
AAAAAAAABAcHBywJCQkzAgICDAAAAAAAAAAAAQEBBwgICCsJCQktBgYGIgICAhEAAAACAAAAAAAAAAAA BwAAAAAAAAAAAwMDFAoKCjYCAgIQAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFBQUaCQkJMgkJCTQJCQkzCgoKNQQEBBcAAAAAAAAAAAQEBBkJ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMPCQkJMgkJCTUJCQk0BAQEGQAAAAAAAAAAAAAA
CQkzCAgIMQMDAxcAAAAAAAAAAwUFBSIJCQk0BwcHLgICAg0AAAAAAAAABQUFBSEHBwcpCQkJMgoKCjYH AAUFBRsKCgo3BQUFHwAAAAAAAAAEBwcHLAkJCTMCAgIMAAAAAAAAAAABAQEHCAgIKwkJCS0GBgYiAgIC
BwcoAQEBCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQYGBh4KCgo2BwcHJwcHBygKCgo2BwcHJwAAAAIA EQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQUFBRoJCQkyCQkJNAkJCTMKCgo1BAQE
AAAAAwMDFAoKCjYHBwcnAQEBCQAAAAAAAAAAAAAAAAAAAAECAgISCQkJMAgICC8BAQEHAAAAAAAAAAAA FwAAAAAAAAAABAQEGQkJCTMICAgxAwMDFwAAAAAAAAADBQUFIgkJCTQHBwcuAgICDQAAAAAAAAAFBQUF
AAABAAAABgUFBRsJCQkzCAgILwICAgoAAAAAAAAAAAAAAAAAAAAAAwMDFgoKCjYGBgYhAAAAAgMDAxMI IQcHBykJCQkyCgoKNgcHBygBAQEKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgYGHgoKCjYHBwcnBwcH
CAguAgICCgAAAAAAAAACBwcHLAcHBywAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICEAoKCjQF KAoKCjYHBwcnAAAAAgAAAAADAwMUCgoKNgcHBycBAQEJAAAAAAAAAAAAAAAAAAAAAQICAhIJCQkwCAgI
BQUdAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMPCQkJMggICCoAAAACAAAAAAAAAAAAAAAEBwcHLgcHBywA LwEBAQcAAAAAAAAAAAAAAAEAAAAGBQUFGwkJCTMICAgvAgICCgAAAAAAAAAAAAAAAAAAAAADAwMWCgoK
AAAEAAAAAAAAAAAAAAACAAAAAAAAAAACAgIJCQkJNAUFBRwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA NgYGBiEAAAACAwMDEwgICC4CAgIKAAAAAAAAAAIHBwcsBwcHLAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAQkJCS0HBwcoAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAABAQEGgoKCjUFBQUhBQUFHwMDAxID AAAAAAACAgIQCgoKNAUFBR0AAAAAAAAAAAAAAAAAAAAAAAAAAAMDAw8JCQkyCAgIKgAAAAIAAAAAAAAA
AwMSCgoKNgQEBBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEICQkJMwgICC8FBQUiBQUFGgMDAxUD AAAAAAQHBwcuBwcHLAAAAAQAAAAAAAAAAAAAAAIAAAAAAAAAAAICAgkJCQk0BQUFHAAAAAAAAAAAAAAA
AwMUAwMDFAQEBBYFBQUcBwcHJQkJCTUHBwcnAAAAAAAAAAAAAAAAAAAAAAAAAAEFBQUfCAgIMAkJCTMJ AAAAAAAAAAAAAAAAAAAAAAAAAAABCQkJLQcHBygAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQaCgoK
CQk0CgoKNwUFBR8GBgYhCQkJNAEBAQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBAQEGAcHBykI NQUFBSEFBQUfAwMDEgMDAxIKCgo2BAQEFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQgJCQkzCAgI
CAgwCQkJMwkJCTUJCQk1CQkJNQkJCTQJCQkzCAgILwYGBiQCAgIOAAAAAAAAAAAAAAAAAAAAAAAAAAEF LwUFBSIFBQUaAwMDFQMDAxQDAwMUBAQEFgUFBRwHBwclCQkJNQcHBycAAAAAAAAAAAAAAAAAAAAAAAAA
BQUfCQkJNAkJCTQJCQk0BwcHKgAAAAQGBgYlCAgILwAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AQUFBR8ICAgwCQkJMwkJCTQKCgo3BQUFHwYGBiEJCQk0AQEBCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAFAgICCwMDAw8CAgIRAwMDDwMDAw4BAQEJAAAAAwAAAAAAAAAAAAAAAAAAAAAA AAAAAAEEBAQYBwcHKQgICDAJCQkzCQkJNQkJCTUJCQk1CQkJNAkJCTMICAgvBgYGJAICAg4AAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAwMDEwkJCS0JCQkyAwMDDgAAAAABAQEHAgICDAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAQUFBR8JCQk0CQkJNAkJCTQHBwcqAAAABAYGBiUICAgvAAAABgAAAAAAAAAAAAAA
AAAAAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUCAgILAwMDDwICAhEDAwMPAwMDDgEBAQkAAAADAAAA
AAAAAAAAAAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAEBAQYCAgIMAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMTCQkJLQkJCTIDAwMOAAAAAAEBAQcCAgIMAAAA
AAAAAAAAAAEBAQcFBQUgBwcHLAgICCsFBQUcAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAACAgIKBgYGIwcHBywHBwcqBAQEGAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAQEBBgICAgwAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAABQgICCoKCgo1CAgIKAgICCsJCQk2BgYGIwAAAAEAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBBwUFBSAHBwcsCAgIKwUFBRwAAAADAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAEBAQkICAgvCQkJMwcHBygHBwcsCgoKNgUFBRwAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgoGBgYjBwcHLAcHByoEBAQYAAAAAQAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEFwoKCjYEBAQXAAAAAAAAAAIFBQUfCQkJNQMDAw8A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCAgIKgoKCjUICAgoCAgIKwkJCTYGBgYjAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBR8JCQk0AgICEQAAAAAAAAADBgYGJgkJCTIB AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBCQgICC8JCQkzBwcHKAcHBywKCgo2BQUF
AQEJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFIAkJCTIAAAAEAAAAAAAAAAAC HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQXCgoKNgQEBBcAAAAAAAAA
AgIMCQkJNQQEBBcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcHBykICAgrAAAAAQAAAAAA AgUFBR8JCQk1AwMDDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFHwkJCTQCAgIRAAAA
AAAAAwMDFAkJCTUCAgIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEGAkJCTUC AAAAAAMGBgYmCQkJMgEBAQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQUgCQkJ
AgIQAAAAAAAAAAAEBAQYCQkJNQICAhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBSEJ MgAAAAQAAAAAAAAAAAICAgwJCQk1BAQEFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwcH
CQkxAQEBCgAAAAAAAAABBQUFIAkJCTMBAQEKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA KQgICCsAAAABAAAAAAAAAAADAwMUCQkJNQICAhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAADBgYGHgoKCjcGBgYmAAAAAAAAAAIICAguCQkJNQQEBBgAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAEBAQYCQkJNQICAhAAAAAAAAAAAAQEBBgJCQk1AgICEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAABQYGBiUKCgo4BQUFHwAAAAABAQEICQkJMggICDICAgIRAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAABQUFIQkJCTEBAQEKAAAAAAAAAAEFBQUgCQkJMwEBAQoAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAMGBgYjCQkJNgcHBycCAgINAAAAAAAAAAADAwMSCAgIKwkJCTYFBQUdAAAAAQAAAAAA AAAAAAAAAAAAAAAAAAAAAAMGBgYeCgoKNwYGBiYAAAAAAAAAAggICC4JCQk1BAQEGAAAAAEAAAAAAAAA
AAAAAAAAAAAAAAAAAAAGBwcHKgkJCTUGBgYjAQEBCgAAAAAAAAABAwMDFwgICC4JCQk0BAQEFgAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAFBgYGJQoKCjgFBQUfAAAAAAEBAQgJCQkyCAgIMgICAhEAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAUFBRoKCgo2BQUFHQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAYGBiQK AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwYGBiMJCQk2BwcHJwICAg0AAAAAAAAAAAMDAxIICAgrCQkJ
Cgo1AgICEQAAAAAAAAAAAAAAAAAAAAAGBgYhCgoKNQQEBBcAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQgI NgUFBR0AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAYHBwcqCQkJNQYGBiMBAQEKAAAAAAAAAAEDAwMXCAgI
CAgqCQkJMwICAgsAAAAAAAAAAAAAAAAAAAAAAAAABAkJCS0HBwcpAAAAAQAAAAAAAAAAAAAAAAAAAAAA LgkJCTQEBAQWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFGgoKCjYFBQUdAAAAAQAAAAAAAAAAAAAA
AAAAAAAAAAAAAAUICAgvBwcHJwAAAAAAAAAAAAAAAAEBAQgJCQkyBQUFIgAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAEBgYGJAoKCjUCAgIRAAAAAAAAAAAAAAAAAAAAAAYGBiEKCgo1BAQEFwAAAAAAAAAAAAAA
AAAAAAAAAAAAAAABAQEKCQkJNAUFBR4AAAAAAAAAAAAAAAAAAAAAAQEBCAkJCTEGBgYjAAAABAAAAAEA AAAAAAAAAAAAAQEBCAgICCoJCQkzAgICCwAAAAAAAAAAAAAAAAAAAAAAAAAECQkJLQcHBykAAAABAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAQEBAQYICAgqBwcHLQAAAAIAAAAAAAAAAAICAg0KCgo1BQUFHAAAAAMA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQgICC8HBwcnAAAAAAAAAAAAAAAAAQEBCAkJCTIFBQUiAAAA
AAABAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQEKCAgILwYGBiYAAAAAAAAAAAAAAAAAAAAAAAAABAcHBywJ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQoJCQk0BQUFHgAAAAAAAAAAAAAAAAAAAAABAQEICQkJ
CQk1CAgIMQgICCkGBgYkBgYGIwYGBiMGBgYkCAgIKgkJCTIJCQk1BwcHJgAAAAAAAAAAAAAAAAEBAQkI MQYGBiMAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAQEBBggICCoHBwctAAAAAgAAAAAAAAAAAgIC
CAgwCQkJNQgICC8HBwcoBgYGIwYGBiMGBgYjBgYGJQcHBywJCQkzCQkJNgYGBh4AAAAAAAAAAAAAAAAA DQoKCjUFBQUcAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgEBAQoICAgvBgYGJgAAAAAAAAAAAAAA
AAAAAAAAAAEBAQkDAwMWBQUFIggICCoICAgwCAgIMQgICDAICAgvBwcHKQUFBSADAwMUAQEBBgAAAAAA AAAAAAAAAAAEBwcHLAkJCTUICAgxCAgIKQYGBiQGBgYjBgYGIwYGBiQICAgqCQkJMgkJCTUHBwcmAAAA
AAAAAAAAAAAAAAACAgIMBAQEGAYGBiMICAgrCAgIMAgICDAICAgwCAgILgcHBygFBQUeAwMDEgAAAAQA AAAAAAAAAAAAAQEBCQgICDAJCQk1CAgILwcHBygGBgYjBgYGIwYGBiMGBgYlBwcHLAkJCTMJCQk2BgYG
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAIAAAACAAAAAQAAAAAA HgAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBCQMDAxYFBQUiCAgIKggICDAICAgxCAgIMAgICC8HBwcpBQUF
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAMAAAACAAAAAgAAAAEA IAMDAxQBAQEGAAAAAAAAAAAAAAAAAAAAAAICAgwEBAQYBgYGIwgICCsICAgwCAgIMAgICDAICAguBwcH
KAUFBR4DAwMSAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAA
AgAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAA
AwAAAAIAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAEBAQkDAwMPAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAQBAQEJAwMDDwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIFBQUfBwcHLQkJCTIJCQk1AwMDDwAAAAAAAAAAAAAA
AAAAAAAEBAQXBQUFHwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMICAguCQkJNAkJCTQHBwctAQEB
CAAAAAIAAAAFAgICDQYGBiQKCgo2BwcHJwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGBgYlCQkJ
NQkJCTQJCQk0CQkJLQgICCoICAguCQkJNQkJCTMEBAQfAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAACBQUFHwcHBy0JCQkyCQkJNQMDAw8AAAAAAAAAAAAAAAAAAAAABAQEFwUFBR8A AAAAAAAFBQUcCgoKNgUFBR8FBQUaBwcHJgcHBykHBwcmBQUFGwICAgoAAAAAAAAAAAAAAAAAAAAAAAAA
AAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCAgILgkJCTQJCQk0BwcHLQEBAQgAAAACAAAABQICAg0G
BgYkCgoKNgcHBycAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgYGJQkJCTUJCQk0CQkJNAkJCS0I
CAgqCAgILgkJCTUJCQkzBAQEHwAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFHAoKCjYF
BQUfBQUFGgcHByYHBwcpBwcHJgUFBRsCAgIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAQEBCwYGBiEAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAABAQELBgYGIQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAEAAAMAAAABACEAAAEBAAMAAAABACEA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAQAAAwAAAAEA
AAECAAMAAAAEAAAR0gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAEKAAMAAAABAAEAAAERAAQAAAABAAAA IQAAAQEAAwAAAAEAIQAAAQIAAwAAAAQAABHSAQMAAwAAAAEAAQAAAQYAAwAAAAEAAgAAAQoAAwAAAAEA
CAESAAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABACEAAAEXAAQAAAABAAARBAEcAAMAAAABAAEA AQAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAAAAEAIQAAARcABAAAAAEA
AAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAFTAAMAAAAEAAAR2odzAAcAAAfYAAAR4gAAAAAACAAIAAgA ABEEARwAAwAAAAEAAQAAASgAAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAABHah3MABwAAB9gA
CAABAAEAAQABAAAH2GFwcGwCIAAAbW50clJHQiBYWVogB9kAAgAZAAsAGgALYWNzcEFQUEwAAAAAYXBw ABHiAAAAAAAIAAgACAAIAAEAAQABAAEAAAfYYXBwbAIgAABtbnRyUkdCIFhZWiAH2QACABkACwAaAAth
bAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Y3NwQVBQTAAAAABhcHBsAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAALZGVzYwAAAQgAAABvZHNjbQAAAXgAAAWcY3BydAAABxQAAAA4d3Rw AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkZXNjAAABCAAAAG9kc2NtAAABeAAABZxj
dAAAB0wAAAAUclhZWgAAB2AAAAAUZ1hZWgAAB3QAAAAUYlhZWgAAB4gAAAAUclRSQwAAB5wAAAAOY2hh cHJ0AAAHFAAAADh3dHB0AAAHTAAAABRyWFlaAAAHYAAAABRnWFlaAAAHdAAAABRiWFlaAAAHiAAAABRy
ZAAAB6wAAAAsYlRSQwAAB5wAAAAOZ1RSQwAAB5wAAAAOZGVzYwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJv VFJDAAAHnAAAAA5jaGFkAAAHrAAAACxiVFJDAAAHnAAAAA5nVFJDAAAHnAAAAA5kZXNjAAAAAAAAABRH
ZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ZW5lcmljIFJHQiBQcm9maWxlAAAAAAAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMAAAAAAAAAHwAAAAxza1NLAAAAKAAAAYRkYURLAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbWx1YwAAAAAAAAAfAAAADHNrU0sA
LgAAAaxjYUVTAAAAJAAAAdp2aVZOAAAAJAAAAf5wdEJSAAAAJgAAAiJ1a1VBAAAAKgAAAkhmckZVAAAA AAAoAAABhGRhREsAAAAuAAABrGNhRVMAAAAkAAAB2nZpVk4AAAAkAAAB/nB0QlIAAAAmAAACInVrVUEA
KAAAAnJodUhVAAAAKAAAApp6aFRXAAAAFgAAAsJuYk5PAAAAJgAAAthjc0NaAAAAIgAAAv5oZUlMAAAA AAAqAAACSGZyRlUAAAAoAAACcmh1SFUAAAAoAAACmnpoVFcAAAAWAAACwm5iTk8AAAAmAAAC2GNzQ1oA
HgAAAyBpdElUAAAAKAAAAz5yb1JPAAAAJAAAA2ZkZURFAAAALAAAA4prb0tSAAAAFgAAA7ZzdlNFAAAA AAAiAAAC/mhlSUwAAAAeAAADIGl0SVQAAAAoAAADPnJvUk8AAAAkAAADZmRlREUAAAAsAAADimtvS1IA
JgAAAth6aENOAAAAFgAAA8xqYUpQAAAAGgAAA+JlbEdSAAAAIgAAA/xwdFBPAAAAJgAABB5ubE5MAAAA AAAWAAADtnN2U0UAAAAmAAAC2HpoQ04AAAAWAAADzGphSlAAAAAaAAAD4mVsR1IAAAAiAAAD/HB0UE8A
KAAABERlc0VTAAAAJgAABB50aFRIAAAAJAAABGx0clRSAAAAIgAABJBmaUZJAAAAKAAABLJockhSAAAA AAAmAAAEHm5sTkwAAAAoAAAERGVzRVMAAAAmAAAEHnRoVEgAAAAkAAAEbHRyVFIAAAAiAAAEkGZpRkkA
KAAABNpwbFBMAAAALAAABQJydVJVAAAAIgAABS5hckVHAAAAJgAABVBlblVTAAAAJgAABXYAVgFhAGUA AAAoAAAEsmhySFIAAAAoAAAE2nBsUEwAAAAsAAAFAnJ1UlUAAAAiAAAFLmFyRUcAAAAmAAAFUGVuVVMA
bwBiAGUAYwBuAP0AIABSAEcAQgAgAHAAcgBvAGYAaQBsAEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIA AAAmAAAFdgBWAWEAZQBvAGIAZQBjAG4A/QAgAFIARwBCACAAcAByAG8AZgBpAGwARwBlAG4AZQByAGUA
ZQBzAGsAcgBpAHYAZQBsAHMAZQBQAGUAcgBmAGkAbAAgAFIARwBCACAAZwBlAG4A6AByAGkAYwBDHqUA bAAgAFIARwBCAC0AYgBlAHMAawByAGkAdgBlAGwAcwBlAFAAZQByAGYAaQBsACAAUgBHAEIAIABnAGUA
dQAgAGgA7ABuAGgAIABSAEcAQgAgAEMAaAB1AG4AZwBQAGUAcgBmAGkAbAAgAFIARwBCACAARwBlAG4A bgDoAHIAaQBjAEMepQB1ACAAaADsAG4AaAAgAFIARwBCACAAQwBoAHUAbgBnAFAAZQByAGYAaQBsACAA
6QByAGkAYwBvBBcEMAQzBDAEOwRMBD0EOAQ5ACAEPwRABD4ERAQwBDkEOwAgAFIARwBCAFAAcgBvAGYA UgBHAEIAIABHAGUAbgDpAHIAaQBjAG8EFwQwBDMEMAQ7BEwEPQQ4BDkAIAQ/BEAEPgREBDAEOQQ7ACAA
aQBsACAAZwDpAG4A6QByAGkAcQB1AGUAIABSAFYAQgDBAGwAdABhAGwA4QBuAG8AcwAgAFIARwBCACAA UgBHAEIAUAByAG8AZgBpAGwAIABnAOkAbgDpAHIAaQBxAHUAZQAgAFIAVgBCAMEAbAB0AGEAbADhAG4A
cAByAG8AZgBpAGyQGnUoACAAUgBHAEIAIIJyX2ljz4/wAEcAZQBuAGUAcgBpAHMAawAgAFIARwBCAC0A bwBzACAAUgBHAEIAIABwAHIAbwBmAGkAbJAadSgAIABSAEcAQgAggnJfaWPPj/AARwBlAG4AZQByAGkA
cAByAG8AZgBpAGwATwBiAGUAYwBuAP0AIABSAEcAQgAgAHAAcgBvAGYAaQBsBeQF6AXVBeQF2QXcACAA cwBrACAAUgBHAEIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A/QAgAFIARwBCACAAcAByAG8AZgBpAGwF
UgBHAEIAIAXbBdwF3AXZAFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAGcAZQBuAGUAcgBpAGMAbwBQAHIA 5AXoBdUF5AXZBdwAIABSAEcAQgAgBdsF3AXcBdkAUAByAG8AZgBpAGwAbwAgAFIARwBCACAAZwBlAG4A
bwBmAGkAbAAgAFIARwBCACAAZwBlAG4AZQByAGkAYwBBAGwAbABnAGUAbQBlAGkAbgBlAHMAIABSAEcA ZQByAGkAYwBvAFAAcgBvAGYAaQBsACAAUgBHAEIAIABnAGUAbgBlAHIAaQBjAEEAbABsAGcAZQBtAGUA
QgAtAFAAcgBvAGYAaQBsx3y8GAAgAFIARwBCACDVBLhc0wzHfGZukBoAIABSAEcAQgAgY8+P8GWHTvZO aQBuAGUAcwAgAFIARwBCAC0AUAByAG8AZgBpAGzHfLwYACAAUgBHAEIAINUEuFzTDMd8Zm6QGgAgAFIA
AIIsACAAUgBHAEIAIDDXMO0w1TChMKQw6wOTA7UDvQO5A7oDzAAgA8ADwQO/A8YDrwO7ACAAUgBHAEIA RwBCACBjz4/wZYdO9k4AgiwAIABSAEcAQgAgMNcw7TDVMKEwpDDrA5MDtQO9A7kDugPMACADwAPBA78D
UABlAHIAZgBpAGwAIABSAEcAQgAgAGcAZQBuAOkAcgBpAGMAbwBBAGwAZwBlAG0AZQBlAG4AIABSAEcA xgOvA7sAIABSAEcAQgBQAGUAcgBmAGkAbAAgAFIARwBCACAAZwBlAG4A6QByAGkAYwBvAEEAbABnAGUA
QgAtAHAAcgBvAGYAaQBlAGwOQg4bDiMORA4fDiUOTAAgAFIARwBCACAOFw4xDkgOJw5EDhsARwBlAG4A bQBlAGUAbgAgAFIARwBCAC0AcAByAG8AZgBpAGUAbA5CDhsOIw5EDh8OJQ5MACAAUgBHAEIAIA4XDjEO
ZQBsACAAUgBHAEIAIABQAHIAbwBmAGkAbABpAFkAbABlAGkAbgBlAG4AIABSAEcAQgAtAHAAcgBvAGYA SA4nDkQOGwBHAGUAbgBlAGwAIABSAEcAQgAgAFAAcgBvAGYAaQBsAGkAWQBsAGUAaQBuAGUAbgAgAFIA
aQBpAGwAaQBHAGUAbgBlAHIAaQENAGsAaQAgAFIARwBCACAAcAByAG8AZgBpAGwAVQBuAGkAdwBlAHIA RwBCAC0AcAByAG8AZgBpAGkAbABpAEcAZQBuAGUAcgBpAQ0AawBpACAAUgBHAEIAIABwAHIAbwBmAGkA
cwBhAGwAbgB5ACAAcAByAG8AZgBpAGwAIABSAEcAQgQeBDEESQQ4BDkAIAQ/BEAEPgREBDgEOwRMACAA bABVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBmAGkAbAAgAFIARwBCBB4EMQRJBDgEOQAgBD8E
UgBHAEIGRQZEBkEAIAYqBjkGMQZKBkEAIABSAEcAQgAgBicGRAY5BicGRQBHAGUAbgBlAHIAaQBjACAA QAQ+BEQEOAQ7BEwAIABSAEcAQgZFBkQGQQAgBioGOQYxBkoGQQAgAFIARwBCACAGJwZEBjkGJwZFAEcA
UgBHAEIAIABQAHIAbwBmAGkAbABldGV4dAAAAABDb3B5cmlnaHQgMjAwNyBBcHBsZSBJbmMuLCBhbGwg ZQBuAGUAcgBpAGMAIABSAEcAQgAgAFAAcgBvAGYAaQBsAGV0ZXh0AAAAAENvcHlyaWdodCAyMDA3IEFw
cmlnaHRzIHJlc2VydmVkLgBYWVogAAAAAAAA81IAAQAAAAEWz1hZWiAAAAAAAAB0TQAAPe4AAAPQWFla cGxlIEluYy4sIGFsbCByaWdodHMgcmVzZXJ2ZWQuAFhZWiAAAAAAAADzUgABAAAAARbPWFlaIAAAAAAA
IAAAAAAAAFp1AACscwAAFzRYWVogAAAAAAAAKBoAABWfAAC4NmN1cnYAAAAAAAAAAQHNAABzZjMyAAAA AHRNAAA97gAAA9BYWVogAAAAAAAAWnUAAKxzAAAXNFhZWiAAAAAAAAAoGgAAFZ8AALg2Y3VydgAAAAAA
AAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbNIlJicoWiRjbGFzc25hbWVYJGNsYXNz AAABAc0AAHNmMzIAAAAAAAEMQgAABd7///MmAAAHkgAA/ZH///ui///9owAAA9wAAMBs0issLS5aJGNs
ZXNfEBBOU0JpdG1hcEltYWdlUmVwoycpKlpOU0ltYWdlUmVwWE5TT2JqZWN00iUmLC1XTlNBcnJheaIs YXNzbmFtZVgkY2xhc3Nlc18QEE5TQml0bWFwSW1hZ2VSZXCjLS8wWk5TSW1hZ2VSZXBYTlNPYmplY3TS
KtIlJi8wXk5TTXV0YWJsZUFycmF5oy8sKtUyMzQ1CjY3ODk6V05TV2hpdGVcTlNDb21wb25lbnRzXE5T KywyM1dOU0FycmF5ojIw0issNTZeTlNNdXRhYmxlQXJyYXmjNTIw1Tg5OjsPPD0+P0BXTlNXaGl0ZVxO
Q29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29sb3JTcGFjZUQwIDAAQzAgMBADgAyAENQ8PT4KP0BBQlROU0lE U0NvbXBvbmVudHNcTlNDb2xvclNwYWNlXxASTlNDdXN0b21Db2xvclNwYWNlRDAgMABDMCAwEAOADIAP
VU5TSUNDV05TTW9kZWwQCYANEACAD9JECkVGV05TLmRhdGFPERFoAAARaGFwcGwCAAAAbW50ckdSQVlY 1EJDRA9FRkdIVE5TSURVTlNJQ0NXTlNNb2RlbBAJgA0QAIAOTxERnAAAEZxhcHBsAgAAAG1udHJHUkFZ
WVogB9wACAAXAA8ALgAPYWNzcEFQUEwAAAAAbm9uZQAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1h WFlaIAfcAAgAFwAPAC4AD2Fjc3BBUFBMAAAAAG5vbmUAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMt
cHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZGVzYwAAAMAA YXBwbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWRlc2MAAADA
AAB5ZHNjbQAAATwAAAfoY3BydAAACSQAAAAjd3RwdAAACUgAAAAUa1RSQwAACVwAAAgMZGVzYwAAAAAA AAAAeWRzY20AAAE8AAAIGmNwcnQAAAlYAAAAI3d0cHQAAAl8AAAAFGtUUkMAAAmQAAAIDGRlc2MAAAAA
AAAfR2VuZXJpYyBHcmF5IEdhbW1hIDIuMiBQcm9maWxlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAH0dlbmVyaWMgR3JheSBHYW1tYSAyLjIgUHJvZmlsZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbHVj
AAAAAAAAHwAAAAxza1NLAAAALgAAAYRkYURLAAAAOAAAAbJjYUVTAAAAOAAAAep2aVZOAAAAQAAAAiJw AAAAAAAAAB8AAAAMc2tTSwAAAC4AAAGEZGFESwAAADoAAAGyY2FFUwAAADgAAAHsdmlWTgAAAEAAAAIk
dEJSAAAASgAAAmJ1a1VBAAAALAAAAqxmckZVAAAAPgAAAthodUhVAAAANAAAAxZ6aFRXAAAAHgAAA0pu cHRCUgAAAEoAAAJkdWtVQQAAACwAAAKuZnJGVQAAAD4AAALaaHVIVQAAADQAAAMYemhUVwAAABoAAANM
Yk5PAAAAOgAAA2hjc0NaAAAAKAAAA6JoZUlMAAAAJAAAA8ppdElUAAAATgAAA+5yb1JPAAAAKgAABDxk a29LUgAAACIAAANmbmJOTwAAADoAAAOIY3NDWgAAACgAAAPCaGVJTAAAACQAAAPqcm9STwAAACoAAAQO
ZURFAAAATgAABGZrb0tSAAAAIgAABLRzdlNFAAAAOAAAAbJ6aENOAAAAHgAABNZqYUpQAAAAJgAABPRl ZGVERQAAAE4AAAQ4aXRJVAAAAE4AAASGc3ZTRQAAADgAAATUemhDTgAAABoAAAUMamFKUAAAACYAAAUm
bEdSAAAAKgAABRpwdFBPAAAAUgAABURubE5MAAAAQAAABZZlc0VTAAAATAAABdZ0aFRIAAAAMgAABiJ0 ZWxHUgAAACoAAAVMcHRQTwAAAFIAAAV2bmxOTAAAAEAAAAXIZXNFUwAAAEwAAAYIdGhUSAAAADIAAAZU
clRSAAAAJAAABlRmaUZJAAAARgAABnhockhSAAAAPgAABr5wbFBMAAAASgAABvxydVJVAAAAOgAAB0Zl dHJUUgAAACQAAAaGZmlGSQAAAEYAAAaqaHJIUgAAAD4AAAbwcGxQTAAAAEoAAAcuYXJFRwAAACwAAAd4
blVTAAAAPAAAB4BhckVHAAAALAAAB7wAVgFhAGUAbwBiAGUAYwBuAOEAIABzAGkAdgDhACAAZwBhAG0A cnVSVQAAADoAAAekZW5VUwAAADwAAAfeAFYBYQBlAG8AYgBlAGMAbgDhACAAcwBpAHYA4QAgAGcAYQBt
YQAgADIALAAyAEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAMgAsADIAIABnAGEAbQBtAGEAcAByAG8A AGEAIAAyACwAMgBHAGUAbgBlAHIAaQBzAGsAIABnAHIA5QAgADIALAAyACAAZwBhAG0AbQBhAC0AcABy
ZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBvAHMAIABnAGUAbgDoAHIAaQBjAGEAIAAyAC4A AG8AZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBvAHMAIABnAGUAbgDoAHIAaQBjAGEAIAAy
MgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBtACAAQwBoAHUAbgBnACAARwBhAG0AbQBhACAA AC4AMgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBtACAAQwBoAHUAbgBnACAARwBhAG0AbQBh
MgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIAaQBjAG8AIABkAGEAIABHAGEAbQBhACAAZABlACAA ACAAMgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIAaQBjAG8AIABkAGEAIABHAGEAbQBhACAAZABl
QwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsETAQ9BDAAIABHAHIAYQB5AC0EMwQwBDwEMAAgADIA ACAAQwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsETAQ9BDAAIABHAHIAYQB5AC0EMwQwBDwEMAAg
LgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1AGUAIABnAHIAaQBzACAAZwBhAG0AbQBhACAA ADIALgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1AGUAIABnAHIAaQBzACAAZwBhAG0AbQBh
MgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/AByAGsAZQAgAGcAYQBtAG0AYQAgADIALgAykBp1 ACAAMgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/AByAGsAZQAgAGcAYQBtAG0AYQAgADIALgAy
KHBwlo5RSV6mACAAMgAuADIAIIJyX2ljz4/wAEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAZwBhAG0A kBp1KHBwlo5RSV6mADIALgAygnJfaWPPj/DHfLwYACDWjMDJACCsELnIACAAMgAuADIAINUEuFzTDMd8
bQBhACAAMgAsADIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A4QAgAWEAZQBkAOEAIABnAGEAbQBhACAA AEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAZwBhAG0AbQBhACAAMgAsADIALQBwAHIAbwBmAGkAbABP
MgAuADIF0gXQBd4F1AAgBdAF5AXVBegAIAXbBdwF3AXZACAAMgAuADIAUAByAG8AZgBpAGwAbwAgAGcA AGIAZQBjAG4A4QAgAWEAZQBkAOEAIABnAGEAbQBhACAAMgAuADIF0gXQBd4F1AAgBdAF5AXVBegAIAXb
cgBpAGcAaQBvACAAZwBlAG4AZQByAGkAYwBvACAAZABlAGwAbABhACAAZwBhAG0AbQBhACAAMgAsADIA BdwF3AXZACAAMgAuADIARwBhAG0AYQAgAGcAcgBpACAAZwBlAG4AZQByAGkAYwEDACAAMgAsADIAQQBs
RwBhAG0AYQAgAGcAcgBpACAAZwBlAG4AZQByAGkAYwEDACAAMgAsADIAQQBsAGwAZwBlAG0AZQBpAG4A AGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAtAFAAcgBvAGYAaQBsACAARwBh
ZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAtAFAAcgBvAGYAaQBsACAARwBhAG0AbQBhACAAMgAsADLH AG0AbQBhACAAMgAsADIAUAByAG8AZgBpAGwAbwAgAGcAcgBpAGcAaQBvACAAZwBlAG4AZQByAGkAYwBv
fLwYACDWjMDJACCsELnIACAAMgAuADIAINUEuFzTDMd8Zm6QGnBwXqZ8+2VwACAAMgAuADIAIGPPj/Bl ACAAZABlAGwAbABhACAAZwBhAG0AbQBhACAAMgAsADIARwBlAG4AZQByAGkAcwBrACAAZwByAOUAIAAy
h072TgCCLDCwMOwwpDCsMPMw3gAgADIALgAyACAw1zDtMNUwoTCkMOsDkwO1A70DuQO6A8wAIAOTA7oD ACwAMgAgAGcAYQBtAG0AYQBwAHIAbwBmAGkAbGZukBpwcF6mfPtlcAAyAC4AMmPPj/Blh072TgCCLDCw
wQO5ACADkwOsA7wDvAOxACAAMgAuADIAUABlAHIAZgBpAGwAIABnAGUAbgDpAHIAaQBjAG8AIABkAGUA MOwwpDCsMPMw3gAgADIALgAyACAw1zDtMNUwoTCkMOsDkwO1A70DuQO6A8wAIAOTA7oDwQO5ACADkwOs
IABjAGkAbgB6AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBtAG0AYQAgADIALAAyAEEAbABnAGUAbQBlAGUA A7wDvAOxACAAMgAuADIAUABlAHIAZgBpAGwAIABnAGUAbgDpAHIAaQBjAG8AIABkAGUAIABjAGkAbgB6
bgAgAGcAcgBpAGoAcwAgAGcAYQBtAG0AYQAgADIALAAyAC0AcAByAG8AZgBpAGUAbABQAGUAcgBmAGkA AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBtAG0AYQAgADIALAAyAEEAbABnAGUAbQBlAGUAbgAgAGcAcgBp
bAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBtAG0AYQAgAGQAZQAgAGcAcgBpAHMAZQBzACAA AGoAcwAgAGcAYQBtAG0AYQAgADIALAAyAC0AcAByAG8AZgBpAGUAbABQAGUAcgBmAGkAbAAgAGcAZQBu
MgAsADIOIw4xDgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4iDkwOFw4xDkgOJw5EDhsAIAAyAC4AMgBHAGUA AOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBtAG0AYQAgAGQAZQAgAGcAcgBpAHMAZQBzACAAMgAsADIOIw4x
bgBlAGwAIABHAHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZAGwAZQBpAG4AZQBuACAAaABhAHIAbQBhAGEA DgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4iDkwOFw4xDkgOJw5EDhsAIAAyAC4AMgBHAGUAbgBlAGwAIABH
bgAgAGcAYQBtAG0AYQAgADIALAAyACAALQBwAHIAbwBmAGkAaQBsAGkARwBlAG4AZQByAGkBDQBrAGkA AHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZAGwAZQBpAG4AZQBuACAAaABhAHIAbQBhAGEAbgAgAGcAYQBt
IABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABwAHIAbwBmAGkAbABVAG4AaQB3AGUAcgBzAGEA AG0AYQAgADIALAAyACAALQBwAHIAbwBmAGkAaQBsAGkARwBlAG4AZQByAGkBDQBrAGkAIABHAHIAYQB5
bABuAHkAIABwAHIAbwBmAGkAbAAgAHMAegBhAHIAbwFbAGMAaQAgAGcAYQBtAG0AYQAgADIALAAyBB4E ACAARwBhAG0AbQBhACAAMgAuADIAIABwAHIAbwBmAGkAbABVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABw
MQRJBDAETwAgBEEENQRABDAETwAgBDMEMAQ8BDwEMAAgADIALAAyAC0EPwRABD4ERAQ4BDsETABHAGUA AHIAbwBmAGkAbAAgAHMAegBhAHIAbwFbAGMAaQAgAGcAYQBtAG0AYQAgADIALAAyBjoGJwZFBicAIAAy
bgBlAHIAaQBjACAARwByAGEAeQAgAEcAYQBtAG0AYQAgADIALgAyACAAUAByAG8AZgBpAGwAZQY6BicG AC4AMgAgBkQGSAZGACAGMQZFBicGLwZKACAGOQYnBkUEHgQxBEkEMARPACAEQQQ1BEAEMARPACAEMwQw
RQYnACAAMgAuADIAIAZEBkgGRgAgBjEGRQYnBi8GSgAgBjkGJwZFdGV4dAAAAABDb3B5cmlnaHQgQXBw BDwEPAQwACAAMgAsADIALQQ/BEAEPgREBDgEOwRMAEcAZQBuAGUAcgBpAGMAIABHAHIAYQB5ACAARwBh
bGUgSW5jLiwgMjAxMgAAWFlaIAAAAAAAAPNRAAEAAAABFsxjdXJ2AAAAAAAABAAAAAAFAAoADwAUABkA AG0AbQBhACAAMgAuADIAIABQAHIAbwBmAGkAbABlAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMu
HgAjACgALQAyADcAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4A LCAyMDEyAABYWVogAAAAAAAA81EAAQAAAAEWzGN1cnYAAAAAAAAEAAAAAAUACgAPABQAGQAeACMAKAAt
sgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+AUUBTAFSAVkB ADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3AHwAgQCGAIsAkACVAJoAnwCkAKkArgCyALcAvADB
YAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksC AMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQETARkBHwElASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1
VAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oD AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHpAfIB+gIDAgwCFAIdAiYCLwI4AkECSwJUAl0CZwJx
lgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwF AnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAMLAxYDIQMtAzgDQwNPA1oDZgNyA34DigOWA6IDrgO6
KwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoGewaMBp0GrwbABtEG4wb1BwcH A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+BIwEmgSoBLYExATTBOEE8AT+BQ0FHAUrBToFSQVY
GQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8J BWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicGNwZIBlkGagZ7BowGnQavBsAG0QbjBvUHBwcZBysHPQdP
ZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kM B2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgyCEYIWghuCIIIlgiqCL4I0gjnCPsJEAklCToJTwlkCXkJjwmk
EgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkP CboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3ArzCwsLIgs5C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxc
JQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQS DHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakNww3eDfgOEw4uDkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96
oxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwW D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPURExExEU8RbRGMEaoRyRHoEgcSJhJFEmQShBKjEsMS4xMD
jxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa EyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTwFRIVNBVWFXgVmxW9FeAWAxYmFkkWbBaPFrIW1hb6
7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qf Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkgGUUZaxmRGbcZ3RoEGioaURp3Gp4axRrsGxQbOxtj
vx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNol G4obshvaHAIcKhxSHHscoxzMHPUdHh1HHXAdmR3DHeweFh5AHmoelB6+HukfEx8+H2kflB+/H+ogFSBB
CSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQpBik4KWspnSnQKgIqNSpoKpsq IGwgmCDEIPAhHCFIIXUhoSHOIfsiJyJVIoIiryLdIwojOCNmI5QjwiPwJB8kTSR8JKsk2iUJJTglaCWX
zysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4WLkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsx Jccl9yYnJlcmhya3JugnGCdJJ3onqyfcKA0oPyhxKKIo1CkGKTgpaymdKdAqAio1KmgqmyrPKwIrNitp
EjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w3 K50r0SwFLDksbiyiLNctDC1BLXYtqy3hLhYuTC6CLrcu7i8kL1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6
1zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/ MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUTNU01hzXCNf02NzZyNq426TckN2A3nDfXOBQ4UDiM
IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWaRd5GIkZnRqtG OMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o76DwnPGU8pDzjPSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/i
8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBP QCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPARANER0SKRM5FEkVVRZpF3kYiRmdGq0bwRzVHe0fA
SU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1TbVShVdVXCVg9WXFapVvdXRFeSV+BY SAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpMcky6TQJNSk2TTdxOJU5uTrdPAE9JT5NP3VAn
L1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9h UHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSPVNtVKFV1VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1ka
omH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1nk2fpaD9olmjsaUNpmmnxakhqn2r3a09r WWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSddeF3JXhpebF69Xw9fYV+zYAVgV2CqYPxhT2GiYfViSWKc
p2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2 YvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeTZ+loP2iWaOxpQ2maafFqSGqfavdrT2una/9sV2yv
Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF84X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqB bQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpxlXHwcktypnMBc11zuHQUdHB0zHUodYV14XY+dpt2+HdW
a4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4efiASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqN d7N4EXhueMx5KnmJeed6RnqlewR7Y3vCfCF8gXzhfUF9oX4BfmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKS
MY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZ gvSDV4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhpiM6JM4mZif6KZIrKizCLlov8jGOMyo0xjZiN/45m
kJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqm js6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSKlPSVX5XJljSWn5cKl3WX4JhMmLiZJJmQmfyaaJrV
i6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660 m0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFHobaiJqKWowajdqPmpFakx6U4pammGqaLpv2nbqfg
JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6Evv+/er/1wHDA7MFnwePC qFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6hrxavi7AAsHWw6rFgsdayS7LCszizrrQltJy1E7WK
X8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrR tgG2ebbwt2i34LhZuNG5SrnCuju6tbsuu6e8IbybvRW9j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPU
PNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724DcBdyK3RDdlt4c3qLfKd+v4Dbg xFHEzsVLxcjGRsbDx0HHv8g9yLzJOsm5yjjKt8s2y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB
veFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw 00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp22vvbgNwF3IrdEN2W3hzeot8p36/gNuC94UThzOJT
5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8mP0p/br+S/7c/23//4AO0iUm 4tvjY+Pr5HPk/OWE5g3mlucf56noMui86Ubp0Opb6uXrcOv77IbtEe2c7ijutO9A78zwWPDl8XLx//KM
SEldTlNNdXRhYmxlRGF0YaNISipWTlNEYXRh0iUmTE1cTlNDb2xvclNwYWNlok4qXE5TQ29sb3JTcGFj 8xnzp/Q09ML1UPXe9m32+/eK+Bn4qPk4+cf6V/rn+3f8B/yY/Sn9uv5L/tz/bf//0issS0xcTlNDb2xv
ZdIlJlBRV05TQ29sb3KiUCrSJSZTVFdOU0ltYWdlolMqXxAPTlNLZXllZEFyY2hpdmVy0VdYVHJvb3SA clNwYWNlok0wXE5TQ29sb3JTcGFjZdIrLE9QV05TQ29sb3KiTzDSKyxSU1dOU0ltYWdlolIwAAgAEQAa
AQAIABEAGgAjAC0AMgA3AEwAUgBdAGQAawB4AH8AhwCJAIsAkACSAJQAnQCiAK0ArwCxALMAuAC7AL0A ACQAKQAyADcASQBMAFEAUwBnAG0AegCBAJAAlwCkAKsAswC1ALcAuQC+AMAAwgDLANAA2wDdAN8A4QDm
vwDBAMMAyADfAOEA4xqhGqYasRq6Gs0a0RrcGuUa6hryGvUa+hsJGw0bGBsgGy0bOhtPG1QbWBtaG1wb AOkA6wDtAO8A9gENASkBKwEtGusa8Br7GwQbFxsbGyYbLxs0GzwbPxtEG1MbVxtiG2obdxuEG5kbnhui
XhtnG2wbcht6G3wbfhuAG4IbhxuPLPss/S0CLRAtFC0bLSAtLS0wLT0tQi1KLU0tUi1aLV0tby1yLXcA G6QbphuoG7Ebthu8G8QbxhvIG8obzC1sLXEtfi2BLY4tky2bLZ4toy2rAAAAAAAAAgEAAAAAAAAAVAAA
AAAAAAACAQAAAAAAAABZAAAAAAAAAAAAAAAAAAAteQ AAAAAAAAAAAAAAAALa4
</mutableData> </mutableData>
</image> </image>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/> <image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="button:GQK-F8-oLr:image" width="40" height="36"> <image name="button:GQK-F8-oLr:image" width="40" height="36">
<mutableData key="keyedArchiveRepresentation"> <mutableData key="keyedArchiveRepresentation">
YnBsaXN0MDDUAQIDBAUGVVZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK8QEgcI YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05T
ExQZHh8jJCsuMTtDR0tPUlUkbnVsbNUJCgsMDQ4PEBESVk5TU2l6ZVYkY2xhc3NcTlNJbWFnZUZsYWdz S2V5ZWRBcmNoaXZlctEICVRyb290gAGvEBELDBkaHxQkKSoxNDdBSUpOUVUkbnVsbNYNDg8QERITFBUW
Vk5TUmVwc1dOU0NvbG9ygAKAERIgwAAAgAOAC1h7NDAsIDM2fdIVChYYWk5TLm9iamVjdHOhF4AEgArS FxhWTlNTaXplXk5TUmVzaXppbmdNb2RlViRjbGFzc1xOU0ltYWdlRmxhZ3NWTlNSZXBzV05TQ29sb3KA
FQoaHaIbHIAFgAaACRAA0iAKISJfEBROU1RJRkZSZXByZXNlbnRhdGlvboAHgAhPER82TU0AKgAAFogA AhAAgBASIMAAAIADgAtYezQwLCAzNn3SGw8cHlpOUy5vYmplY3RzoR2ABIAK0hsPICOiISKABYAGgAnT
DyUmJygUXxAUTlNUSUZGUmVwcmVzZW50YXRpb25fEBlOU0ludGVybmFsTGF5b3V0RGlyZWN0aW9ugAiA
B08RHzZNTQAqAAAWiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
@ -1583,35 +1587,34 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAABhgAABkYAAAZBQAABgAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAUAAAYYAAAZGAAAGQUAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsAATyb AAAAAAAAAAAAOwABPJsABJ7IAAXMyAAFzJ0ABKA/AAFBAQAAAgAAAAAAAAAAAAAAAAAAAAACAgICAQEB
AASeyAAFzMgABcydAASgPwABQQEAAAIAAAAAAAAAAAAAAAAAAAAAAgICAgEBAQEAAAAACgoKCgQEBAQA AQAAAAAKCgoKBAQEBAAAAAAAAAAACQkJCQkJCQkAAAAAAAAAAAAAAAAAAAAAAAAAAAkJCQkHBwcHAAAA
AAAAAAAAAAkJCQkJCQkJAAAAAAAAAAAAAAAAAAAAAAAAAAAJCQkJBwcHBwAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASQACS9gABtz7AAf/+wAH
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkAAkvYAAbc+wAH//sAB//7AAf/+wAH/9sABt9Q //sAB//7AAf/2wAG31AAAlIAAAAAAAAAAAAAAAAAAAAAW1tbW6KioqKZmZmZ29vb22BgYGIICAgIh4eH
AAJSAAAAAAAAAAAAAAAAAAAAAFtbW1uioqKimZmZmdvb29tgYGBiCAgICIeHh4nJycnJycnJynp6enwH icnJycnJycnKenp6fAcHBwcAAAAAEhISEpOTk5XS0tLTy8vLzHh4eHoHBwcHAAAAAAAAAAAAAAAAAAAA
BwcHAAAAABISEhKTk5OV0tLS08vLy8x4eHh6BwcHBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAAF7wABcD7AAf/+wAH//sAB//7AAf/+wAH//sAB//AAAXEGgAA
AAAAAAAAABYAABe8AAXA+wAH//sAB//7AAf/+wAH//sAB//7AAf/wAAFxBoAABsAAAAAAAAAAAAAAABw GwAAAAAAAAAAAAAAAHBwcHD/////gYGBgygoKCoNDQ0NiIiIiq6urq8XFxcXFxcXGbm5ublycnJyAAAA
cHBw/////4GBgYMoKCgqDQ0NDYiIiIqurq6vFxcXFxcXFxm5ubm5cnJycgAAAACYmJiZwcHBwSgoKCgt AJiYmJnBwcHBKCgoKC0tLS/T09PUV1dXVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
LS0v09PT1FdXV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEAAFG6wAG7/sAB//7 AEQAAUbrAAbv+wAH//sAB//7AAf/+wAH//sAB//7AAf/7AAG8EoAAkwAAAAAAAAAAAAAAAB0dHR00NDQ
AAf/+wAH//sAB//7AAf/+wAH/+wABvBKAAJMAAAAAAAAAAAAAAAAdHR0dNDQ0NAAAAAAAAAAAAcHBwfU 0AAAAAAAAAAABwcHB9TU1NWRkZGTY2NjY2NjY2Ojo6OjyMjIyBYWFhbd3d3dOzs7PQAAAAAAAAAAFxcX
1NTVkZGRk2NjY2NjY2Njo6Ojo8jIyMgWFhYW3d3d3Ts7Oz0AAAAAAAAAABcXFxkVFRUVAAAAAAAAAAAA GRUVFRUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSAAJU8gAG9vsAB//7AAf/+wAH
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUgACVPIABvb7AAf/+wAH//sAB//7AAf/+wAH//sAB//0 //sAB//7AAf/+wAH//QABvhcAAJeAAAAAAAAAAAAAAAAdnZ2dre3t7cAAAAAAAAAAA4ODg7g4ODhoaGh
AAb4XAACXgAAAAAAAAAAAAAAAHZ2dna3t7e3AAAAAAAAAAAODg4O4ODg4aGhoaGMjIyMjIyMjIaGhoZS oYyMjIyMjIyMhoaGhlJSUlQcHBwc4eHh4ioqKioAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
UlJUHBwcHOHh4eIqKioqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAOAABOeQABuj7AAf/+wAH//sAB//7AAf/+wAH//sAB//mAAbqPgAB
AAAAAAAAADgAATnkAAbo+wAH//sAB//7AAf/+wAH//sAB//7AAf/5gAG6j4AAT8AAAAAAAAAAAAAAAB2 PwAAAAAAAAAAAAAAAHZ2dna4uLi4AAAAAAAAAAAEBAQEwsLCw2JiYmIAAAAAAAAAADMzMzNeXl5eCQkJ
dnZ2uLi4uAAAAAAAAAAABAQEBMLCwsNiYmJiAAAAAAAAAAAzMzMzXl5eXgkJCQnNzc3OaWlpaQAAAAAA Cc3Nzc5paWlpAAAAAAAAAABxcXFzWVlZWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAcXFxc1lZWVsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAMogAEpfsAB//7 AAsAAAyiAASl+wAH//sAB//7AAf/+wAH//sAB//7AAf/pgAEqQ8AABAAAAAAAAAAAAAAAAB4eHh4vLy8
AAf/+wAH//sAB//7AAf/+wAH/6YABKkPAAAQAAAAAAAAAAAAAAAAeHh4eLy8vLwAAAAAAAAAAAAAAABI vAAAAAAAAAAAAAAAAEhISEjX19fYmZmZmouLi43a2trbYmJiZAAAAABRUVFT39/f35ubm5yenp6f3Nzc
SEhI19fX2JmZmZqLi4uN2tra22JiYmQAAAAAUVFRU9/f39+bm5ucnp6en9zc3N05OTk5AAAAAAAAAAAA 3Tk5OTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKgABK7QABbf1AAb5+wAH
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoAASu0AAW39QAG+fsAB//7AAf/9gAG+rYABbks //sAB//2AAb6tgAFuSwAAS0AAAAAAAAAAAAAAAAAAAAAKioqKkFBQUMAAAAAAAAAAAAAAAAAAAAAJiYm
AAEtAAAAAAAAAAAAAAAAAAAAACoqKipBQUFDAAAAAAAAAAAAAAAAAAAAACYmJihubm5wcXFxczIyMjQA KG5ubnBxcXFzMjIyNAAAAAAAAAAAAAAAADAwMDB0dHR0bGxsbiMjIyMAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAwMDAwdHR0dGxsbG4jIyMjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAaYwACZZYABJmVAASYZQACZxwAAB0AAAAAAAAA
AAAAAAAAAAAAAAAAAAAAGQAAGmMAAmWWAASZlQAEmGUAAmccAAAdAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAABQAABgQAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAFAAAGBAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
@ -1648,127 +1651,127 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
EAEAAAMAAAABACgAAAEBAAMAAAABACQAAAECAAMAAAAEAAAXTgEDAAMAAAABAAEAAAEGAAMAAAABAAIA AAAAAAAAAAAAAAAAAAAQAQAAAwAAAAEAKAAAAQEAAwAAAAEAJAAAAQIAAwAAAAQAABdOAQMAAwAAAAEA
AAEKAAMAAAABAAEAAAERAAQAAAABAAAACAESAAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABACQA AQAAAQYAAwAAAAEAAgAAAQoAAwAAAAEAAQAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEA
AAEXAAQAAAABAAAWgAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAFTAAMAAAAEAAAX BAAAARYAAwAAAAEAJAAAARcABAAAAAEAABaAARwAAwAAAAEAAQAAASgAAwAAAAEAAgAAAVIAAwAAAAEA
VodzAAcAAAfYAAAXXgAAAAAACAAIAAgACAABAAEAAQABAAAH2GFwcGwCIAAAbW50clJHQiBYWVogB9kA AQAAAVMAAwAAAAQAABdWh3MABwAAB9gAABdeAAAAAAAIAAgACAAIAAEAAQABAAEAAAfYYXBwbAIgAABt
AgAZAAsAGgALYWNzcEFQUEwAAAAAYXBwbAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsAAAA bnRyUkdCIFhZWiAH2QACABkACwAaAAthY3NwQVBQTAAAAABhcHBsAAAAAAAAAAAAAAAAAAAAAAAA9tYA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALZGVzYwAAAQgAAABvZHNj AQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtk
bQAAAXgAAAWcY3BydAAABxQAAAA4d3RwdAAAB0wAAAAUclhZWgAAB2AAAAAUZ1hZWgAAB3QAAAAUYlhZ ZXNjAAABCAAAAG9kc2NtAAABeAAABZxjcHJ0AAAHFAAAADh3dHB0AAAHTAAAABRyWFlaAAAHYAAAABRn
WgAAB4gAAAAUclRSQwAAB5wAAAAOY2hhZAAAB6wAAAAsYlRSQwAAB5wAAAAOZ1RSQwAAB5wAAAAOZGVz WFlaAAAHdAAAABRiWFlaAAAHiAAAABRyVFJDAAAHnAAAAA5jaGFkAAAHrAAAACxiVFJDAAAHnAAAAA5n
YwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUA VFJDAAAHnAAAAA5kZXNjAAAAAAAAABRHZW5lcmljIFJHQiBQcm9maWxlAAAAAAAAAAAAAAAUR2VuZXJp
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMAAAAAAAAA YyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
HwAAAAxza1NLAAAAKAAAAYRkYURLAAAALgAAAaxjYUVTAAAAJAAAAdp2aVZOAAAAJAAAAf5wdEJSAAAA AAAAbWx1YwAAAAAAAAAfAAAADHNrU0sAAAAoAAABhGRhREsAAAAuAAABrGNhRVMAAAAkAAAB2nZpVk4A
JgAAAiJ1a1VBAAAAKgAAAkhmckZVAAAAKAAAAnJodUhVAAAAKAAAApp6aFRXAAAAFgAAAsJuYk5PAAAA AAAkAAAB/nB0QlIAAAAmAAACInVrVUEAAAAqAAACSGZyRlUAAAAoAAACcmh1SFUAAAAoAAACmnpoVFcA
JgAAAthjc0NaAAAAIgAAAv5oZUlMAAAAHgAAAyBpdElUAAAAKAAAAz5yb1JPAAAAJAAAA2ZkZURFAAAA AAAWAAACwm5iTk8AAAAmAAAC2GNzQ1oAAAAiAAAC/mhlSUwAAAAeAAADIGl0SVQAAAAoAAADPnJvUk8A
LAAAA4prb0tSAAAAFgAAA7ZzdlNFAAAAJgAAAth6aENOAAAAFgAAA8xqYUpQAAAAGgAAA+JlbEdSAAAA AAAkAAADZmRlREUAAAAsAAADimtvS1IAAAAWAAADtnN2U0UAAAAmAAAC2HpoQ04AAAAWAAADzGphSlAA
IgAAA/xwdFBPAAAAJgAABB5ubE5MAAAAKAAABERlc0VTAAAAJgAABB50aFRIAAAAJAAABGx0clRSAAAA AAAaAAAD4mVsR1IAAAAiAAAD/HB0UE8AAAAmAAAEHm5sTkwAAAAoAAAERGVzRVMAAAAmAAAEHnRoVEgA
IgAABJBmaUZJAAAAKAAABLJockhSAAAAKAAABNpwbFBMAAAALAAABQJydVJVAAAAIgAABS5hckVHAAAA AAAkAAAEbHRyVFIAAAAiAAAEkGZpRkkAAAAoAAAEsmhySFIAAAAoAAAE2nBsUEwAAAAsAAAFAnJ1UlUA
JgAABVBlblVTAAAAJgAABXYAVgFhAGUAbwBiAGUAYwBuAP0AIABSAEcAQgAgAHAAcgBvAGYAaQBsAEcA AAAiAAAFLmFyRUcAAAAmAAAFUGVuVVMAAAAmAAAFdgBWAWEAZQBvAGIAZQBjAG4A/QAgAFIARwBCACAA
ZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZQBQAGUAcgBmAGkAbAAgAFIA cAByAG8AZgBpAGwARwBlAG4AZQByAGUAbAAgAFIARwBCAC0AYgBlAHMAawByAGkAdgBlAGwAcwBlAFAA
RwBCACAAZwBlAG4A6AByAGkAYwBDHqUAdQAgAGgA7ABuAGgAIABSAEcAQgAgAEMAaAB1AG4AZwBQAGUA ZQByAGYAaQBsACAAUgBHAEIAIABnAGUAbgDoAHIAaQBjAEMepQB1ACAAaADsAG4AaAAgAFIARwBCACAA
cgBmAGkAbAAgAFIARwBCACAARwBlAG4A6QByAGkAYwBvBBcEMAQzBDAEOwRMBD0EOAQ5ACAEPwRABD4E QwBoAHUAbgBnAFAAZQByAGYAaQBsACAAUgBHAEIAIABHAGUAbgDpAHIAaQBjAG8EFwQwBDMEMAQ7BEwE
RAQwBDkEOwAgAFIARwBCAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1AGUAIABSAFYAQgDBAGwA PQQ4BDkAIAQ/BEAEPgREBDAEOQQ7ACAAUgBHAEIAUAByAG8AZgBpAGwAIABnAOkAbgDpAHIAaQBxAHUA
dABhAGwA4QBuAG8AcwAgAFIARwBCACAAcAByAG8AZgBpAGyQGnUoACAAUgBHAEIAIIJyX2ljz4/wAEcA ZQAgAFIAVgBCAMEAbAB0AGEAbADhAG4AbwBzACAAUgBHAEIAIABwAHIAbwBmAGkAbJAadSgAIABSAEcA
ZQBuAGUAcgBpAHMAawAgAFIARwBCAC0AcAByAG8AZgBpAGwATwBiAGUAYwBuAP0AIABSAEcAQgAgAHAA QgAggnJfaWPPj/AARwBlAG4AZQByAGkAcwBrACAAUgBHAEIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A
cgBvAGYAaQBsBeQF6AXVBeQF2QXcACAAUgBHAEIAIAXbBdwF3AXZAFAAcgBvAGYAaQBsAG8AIABSAEcA /QAgAFIARwBCACAAcAByAG8AZgBpAGwF5AXoBdUF5AXZBdwAIABSAEcAQgAgBdsF3AXcBdkAUAByAG8A
QgAgAGcAZQBuAGUAcgBpAGMAbwBQAHIAbwBmAGkAbAAgAFIARwBCACAAZwBlAG4AZQByAGkAYwBBAGwA ZgBpAGwAbwAgAFIARwBCACAAZwBlAG4AZQByAGkAYwBvAFAAcgBvAGYAaQBsACAAUgBHAEIAIABnAGUA
bABnAGUAbQBlAGkAbgBlAHMAIABSAEcAQgAtAFAAcgBvAGYAaQBsx3y8GAAgAFIARwBCACDVBLhc0wzH bgBlAHIAaQBjAEEAbABsAGcAZQBtAGUAaQBuAGUAcwAgAFIARwBCAC0AUAByAG8AZgBpAGzHfLwYACAA
fGZukBoAIABSAEcAQgAgY8+P8GWHTvZOAIIsACAAUgBHAEIAIDDXMO0w1TChMKQw6wOTA7UDvQO5A7oD UgBHAEIAINUEuFzTDMd8Zm6QGgAgAFIARwBCACBjz4/wZYdO9k4AgiwAIABSAEcAQgAgMNcw7TDVMKEw
zAAgA8ADwQO/A8YDrwO7ACAAUgBHAEIAUABlAHIAZgBpAGwAIABSAEcAQgAgAGcAZQBuAOkAcgBpAGMA pDDrA5MDtQO9A7kDugPMACADwAPBA78DxgOvA7sAIABSAEcAQgBQAGUAcgBmAGkAbAAgAFIARwBCACAA
bwBBAGwAZwBlAG0AZQBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBlAGwOQg4bDiMORA4fDiUOTAAgAFIA ZwBlAG4A6QByAGkAYwBvAEEAbABnAGUAbQBlAGUAbgAgAFIARwBCAC0AcAByAG8AZgBpAGUAbA5CDhsO
RwBCACAOFw4xDkgOJw5EDhsARwBlAG4AZQBsACAAUgBHAEIAIABQAHIAbwBmAGkAbABpAFkAbABlAGkA Iw5EDh8OJQ5MACAAUgBHAEIAIA4XDjEOSA4nDkQOGwBHAGUAbgBlAGwAIABSAEcAQgAgAFAAcgBvAGYA
bgBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBpAGwAaQBHAGUAbgBlAHIAaQENAGsAaQAgAFIARwBCACAA aQBsAGkAWQBsAGUAaQBuAGUAbgAgAFIARwBCAC0AcAByAG8AZgBpAGkAbABpAEcAZQBuAGUAcgBpAQ0A
cAByAG8AZgBpAGwAVQBuAGkAdwBlAHIAcwBhAGwAbgB5ACAAcAByAG8AZgBpAGwAIABSAEcAQgQeBDEE awBpACAAUgBHAEIAIABwAHIAbwBmAGkAbABVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBmAGkA
SQQ4BDkAIAQ/BEAEPgREBDgEOwRMACAAUgBHAEIGRQZEBkEAIAYqBjkGMQZKBkEAIABSAEcAQgAgBicG bAAgAFIARwBCBB4EMQRJBDgEOQAgBD8EQAQ+BEQEOAQ7BEwAIABSAEcAQgZFBkQGQQAgBioGOQYxBkoG
RAY5BicGRQBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABldGV4dAAAAABDb3B5cmln QQAgAFIARwBCACAGJwZEBjkGJwZFAEcAZQBuAGUAcgBpAGMAIABSAEcAQgAgAFAAcgBvAGYAaQBsAGV0
aHQgMjAwNyBBcHBsZSBJbmMuLCBhbGwgcmlnaHRzIHJlc2VydmVkLgBYWVogAAAAAAAA81IAAQAAAAEW ZXh0AAAAAENvcHlyaWdodCAyMDA3IEFwcGxlIEluYy4sIGFsbCByaWdodHMgcmVzZXJ2ZWQuAFhZWiAA
z1hZWiAAAAAAAAB0TQAAPe4AAAPQWFlaIAAAAAAAAFp1AACscwAAFzRYWVogAAAAAAAAKBoAABWfAAC4 AAAAAADzUgABAAAAARbPWFlaIAAAAAAAAHRNAAA97gAAA9BYWVogAAAAAAAAWnUAAKxzAAAXNFhZWiAA
NmN1cnYAAAAAAAAAAQHNAABzZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADA AAAAAAAoGgAAFZ8AALg2Y3VydgAAAAAAAAABAc0AAHNmMzIAAAAAAAEMQgAABd7///MmAAAHkgAA/ZH/
bNIlJicoWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBOU0JpdG1hcEltYWdlUmVwoycpKlpOU0ltYWdlUmVw //ui///9owAAA9wAAMBs0issLS5aJGNsYXNzbmFtZVgkY2xhc3Nlc18QEE5TQml0bWFwSW1hZ2VSZXCj
WE5TT2JqZWN00iUmLC1XTlNBcnJheaIsKtIlJi8wXk5TTXV0YWJsZUFycmF5oy8sKtUyMzQ1CjY3ODk6 LS8wWk5TSW1hZ2VSZXBYTlNPYmplY3TSKywyM1dOU0FycmF5ojIw0issNTZeTlNNdXRhYmxlQXJyYXmj
V05TV2hpdGVcTlNDb21wb25lbnRzXE5TQ29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29sb3JTcGFjZUQwIDAA NTIw1Tg5OjsPPD0+P0BXTlNXaGl0ZVxOU0NvbXBvbmVudHNcTlNDb2xvclNwYWNlXxASTlNDdXN0b21D
QzAgMBADgAyAENQ8PT4KP0BBQlROU0lEVU5TSUNDV05TTW9kZWwQCYANEACAD9JECkVGV05TLmRhdGFP b2xvclNwYWNlRDAgMABDMCAwEAOADIAP1EJDRA9FRkdIVE5TSURVTlNJQ0NXTlNNb2RlbBAJgA0QAIAO
ERFoAAARaGFwcGwCAAAAbW50ckdSQVlYWVogB9wACAAXAA8ALgAPYWNzcEFQUEwAAAAAbm9uZQAAAAAA TxERnAAAEZxhcHBsAgAAAG1udHJHUkFZWFlaIAfcAAgAFwAPAC4AD2Fjc3BBUFBMAAAAAG5vbmUAAAAA
AAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAD21gABAAAAANMtYXBwbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAFZGVzYwAAAMAAAAB5ZHNjbQAAATwAAAfoY3BydAAACSQAAAAjd3RwdAAACUgA AAAAAAAAAAAAAAAAAAAABWRlc2MAAADAAAAAeWRzY20AAAE8AAAIGmNwcnQAAAlYAAAAI3d0cHQAAAl8
AAAUa1RSQwAACVwAAAgMZGVzYwAAAAAAAAAfR2VuZXJpYyBHcmF5IEdhbW1hIDIuMiBQcm9maWxlAAAA AAAAFGtUUkMAAAmQAAAIDGRlc2MAAAAAAAAAH0dlbmVyaWMgR3JheSBHYW1tYSAyLjIgUHJvZmlsZQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMAAAAAAAAAHwAAAAxza1NLAAAALgAAAYRkYURLAAAAOAAAAbJj AAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAB8AAAAMc2tTSwAAAC4AAAGEZGFESwAAADoAAAGy
YUVTAAAAOAAAAep2aVZOAAAAQAAAAiJwdEJSAAAASgAAAmJ1a1VBAAAALAAAAqxmckZVAAAAPgAAAtho Y2FFUwAAADgAAAHsdmlWTgAAAEAAAAIkcHRCUgAAAEoAAAJkdWtVQQAAACwAAAKuZnJGVQAAAD4AAALa
dUhVAAAANAAAAxZ6aFRXAAAAHgAAA0puYk5PAAAAOgAAA2hjc0NaAAAAKAAAA6JoZUlMAAAAJAAAA8pp aHVIVQAAADQAAAMYemhUVwAAABoAAANMa29LUgAAACIAAANmbmJOTwAAADoAAAOIY3NDWgAAACgAAAPC
dElUAAAATgAAA+5yb1JPAAAAKgAABDxkZURFAAAATgAABGZrb0tSAAAAIgAABLRzdlNFAAAAOAAAAbJ6 aGVJTAAAACQAAAPqcm9STwAAACoAAAQOZGVERQAAAE4AAAQ4aXRJVAAAAE4AAASGc3ZTRQAAADgAAATU
aENOAAAAHgAABNZqYUpQAAAAJgAABPRlbEdSAAAAKgAABRpwdFBPAAAAUgAABURubE5MAAAAQAAABZZl emhDTgAAABoAAAUMamFKUAAAACYAAAUmZWxHUgAAACoAAAVMcHRQTwAAAFIAAAV2bmxOTAAAAEAAAAXI
c0VTAAAATAAABdZ0aFRIAAAAMgAABiJ0clRSAAAAJAAABlRmaUZJAAAARgAABnhockhSAAAAPgAABr5w ZXNFUwAAAEwAAAYIdGhUSAAAADIAAAZUdHJUUgAAACQAAAaGZmlGSQAAAEYAAAaqaHJIUgAAAD4AAAbw
bFBMAAAASgAABvxydVJVAAAAOgAAB0ZlblVTAAAAPAAAB4BhckVHAAAALAAAB7wAVgFhAGUAbwBiAGUA cGxQTAAAAEoAAAcuYXJFRwAAACwAAAd4cnVSVQAAADoAAAekZW5VUwAAADwAAAfeAFYBYQBlAG8AYgBl
YwBuAOEAIABzAGkAdgDhACAAZwBhAG0AYQAgADIALAAyAEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAA AGMAbgDhACAAcwBpAHYA4QAgAGcAYQBtAGEAIAAyACwAMgBHAGUAbgBlAHIAaQBzAGsAIABnAHIA5QAg
MgAsADIAIABnAGEAbQBtAGEAcAByAG8AZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBvAHMA ADIALAAyACAAZwBhAG0AbQBhAC0AcAByAG8AZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBv
IABnAGUAbgDoAHIAaQBjAGEAIAAyAC4AMgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBtACAA AHMAIABnAGUAbgDoAHIAaQBjAGEAIAAyAC4AMgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBt
QwBoAHUAbgBnACAARwBhAG0AbQBhACAAMgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIAaQBjAG8A ACAAQwBoAHUAbgBnACAARwBhAG0AbQBhACAAMgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIAaQBj
IABkAGEAIABHAGEAbQBhACAAZABlACAAQwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsETAQ9BDAA AG8AIABkAGEAIABHAGEAbQBhACAAZABlACAAQwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsETAQ9
IABHAHIAYQB5AC0EMwQwBDwEMAAgADIALgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1AGUA BDAAIABHAHIAYQB5AC0EMwQwBDwEMAAgADIALgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1
IABnAHIAaQBzACAAZwBhAG0AbQBhACAAMgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/AByAGsA AGUAIABnAHIAaQBzACAAZwBhAG0AbQBhACAAMgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/ABy
ZQAgAGcAYQBtAG0AYQAgADIALgAykBp1KHBwlo5RSV6mACAAMgAuADIAIIJyX2ljz4/wAEcAZQBuAGUA AGsAZQAgAGcAYQBtAG0AYQAgADIALgAykBp1KHBwlo5RSV6mADIALgAygnJfaWPPj/DHfLwYACDWjMDJ
cgBpAHMAawAgAGcAcgDlACAAZwBhAG0AbQBhACAAMgAsADIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A ACCsELnIACAAMgAuADIAINUEuFzTDMd8AEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAZwBhAG0AbQBh
4QAgAWEAZQBkAOEAIABnAGEAbQBhACAAMgAuADIF0gXQBd4F1AAgBdAF5AXVBegAIAXbBdwF3AXZACAA ACAAMgAsADIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A4QAgAWEAZQBkAOEAIABnAGEAbQBhACAAMgAu
MgAuADIAUAByAG8AZgBpAGwAbwAgAGcAcgBpAGcAaQBvACAAZwBlAG4AZQByAGkAYwBvACAAZABlAGwA ADIF0gXQBd4F1AAgBdAF5AXVBegAIAXbBdwF3AXZACAAMgAuADIARwBhAG0AYQAgAGcAcgBpACAAZwBl
bABhACAAZwBhAG0AbQBhACAAMgAsADIARwBhAG0AYQAgAGcAcgBpACAAZwBlAG4AZQByAGkAYwEDACAA AG4AZQByAGkAYwEDACAAMgAsADIAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBm
MgAsADIAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAtAFAAcgBvAGYA AGUAbgAtAFAAcgBvAGYAaQBsACAARwBhAG0AbQBhACAAMgAsADIAUAByAG8AZgBpAGwAbwAgAGcAcgBp
aQBsACAARwBhAG0AbQBhACAAMgAsADLHfLwYACDWjMDJACCsELnIACAAMgAuADIAINUEuFzTDMd8Zm6Q AGcAaQBvACAAZwBlAG4AZQByAGkAYwBvACAAZABlAGwAbABhACAAZwBhAG0AbQBhACAAMgAsADIARwBl
GnBwXqZ8+2VwACAAMgAuADIAIGPPj/Blh072TgCCLDCwMOwwpDCsMPMw3gAgADIALgAyACAw1zDtMNUw AG4AZQByAGkAcwBrACAAZwByAOUAIAAyACwAMgAgAGcAYQBtAG0AYQBwAHIAbwBmAGkAbGZukBpwcF6m
oTCkMOsDkwO1A70DuQO6A8wAIAOTA7oDwQO5ACADkwOsA7wDvAOxACAAMgAuADIAUABlAHIAZgBpAGwA fPtlcAAyAC4AMmPPj/Blh072TgCCLDCwMOwwpDCsMPMw3gAgADIALgAyACAw1zDtMNUwoTCkMOsDkwO1
IABnAGUAbgDpAHIAaQBjAG8AIABkAGUAIABjAGkAbgB6AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBtAG0A A70DuQO6A8wAIAOTA7oDwQO5ACADkwOsA7wDvAOxACAAMgAuADIAUABlAHIAZgBpAGwAIABnAGUAbgDp
YQAgADIALAAyAEEAbABnAGUAbQBlAGUAbgAgAGcAcgBpAGoAcwAgAGcAYQBtAG0AYQAgADIALAAyAC0A AHIAaQBjAG8AIABkAGUAIABjAGkAbgB6AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBtAG0AYQAgADIALAAy
cAByAG8AZgBpAGUAbABQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBtAG0A AEEAbABnAGUAbQBlAGUAbgAgAGcAcgBpAGoAcwAgAGcAYQBtAG0AYQAgADIALAAyAC0AcAByAG8AZgBp
YQAgAGQAZQAgAGcAcgBpAHMAZQBzACAAMgAsADIOIw4xDgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4iDkwO AGUAbABQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBtAG0AYQAgAGQAZQAg
Fw4xDkgOJw5EDhsAIAAyAC4AMgBHAGUAbgBlAGwAIABHAHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZAGwA AGcAcgBpAHMAZQBzACAAMgAsADIOIw4xDgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4iDkwOFw4xDkgOJw5E
ZQBpAG4AZQBuACAAaABhAHIAbQBhAGEAbgAgAGcAYQBtAG0AYQAgADIALAAyACAALQBwAHIAbwBmAGkA DhsAIAAyAC4AMgBHAGUAbgBlAGwAIABHAHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZAGwAZQBpAG4AZQBu
aQBsAGkARwBlAG4AZQByAGkBDQBrAGkAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABwAHIA ACAAaABhAHIAbQBhAGEAbgAgAGcAYQBtAG0AYQAgADIALAAyACAALQBwAHIAbwBmAGkAaQBsAGkARwBl
bwBmAGkAbABVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBmAGkAbAAgAHMAegBhAHIAbwFbAGMA AG4AZQByAGkBDQBrAGkAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABwAHIAbwBmAGkAbABV
aQAgAGcAYQBtAG0AYQAgADIALAAyBB4EMQRJBDAETwAgBEEENQRABDAETwAgBDMEMAQ8BDwEMAAgADIA AG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBmAGkAbAAgAHMAegBhAHIAbwFbAGMAaQAgAGcAYQBt
LAAyAC0EPwRABD4ERAQ4BDsETABHAGUAbgBlAHIAaQBjACAARwByAGEAeQAgAEcAYQBtAG0AYQAgADIA AG0AYQAgADIALAAyBjoGJwZFBicAIAAyAC4AMgAgBkQGSAZGACAGMQZFBicGLwZKACAGOQYnBkUEHgQx
LgAyACAAUAByAG8AZgBpAGwAZQY6BicGRQYnACAAMgAuADIAIAZEBkgGRgAgBjEGRQYnBi8GSgAgBjkG BEkEMARPACAEQQQ1BEAEMARPACAEMwQwBDwEPAQwACAAMgAsADIALQQ/BEAEPgREBDgEOwRMAEcAZQBu
JwZFdGV4dAAAAABDb3B5cmlnaHQgQXBwbGUgSW5jLiwgMjAxMgAAWFlaIAAAAAAAAPNRAAEAAAABFsxj AGUAcgBpAGMAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABQAHIAbwBmAGkAbABlAAB0ZXh0
dXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAyADcAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIA AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDEyAABYWVogAAAAAAAA81EAAQAAAAEWzGN1cnYAAAAA
dwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4AsgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0B AAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3AHwAgQCG
EwEZAR8BJQErATIBOAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB AIsAkACVAJoAnwCkAKkArgCyALcAvADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQETARkBHwEl
6QHyAfoCAwIMAhQCHQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwAD ASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHpAfIB+gID
CwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEE AgwCFAIdAiYCLwI4AkECSwJUAl0CZwJxAnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAMLAxYDIQMt
fgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcG AzgDQwNPA1oDZgNyA34DigOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+BIwEmgSo
SAZZBmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoI BLYExATTBOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicGNwZIBlkGagZ7
bgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK BowGnQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgyCEYIWghuCIIIlgiq
8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN CL4I0gjnCPsJEAklCToJTwlkCXkJjwmkCboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3ArzCwsLIgs5
3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMR C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakNww3eDfgOEw4u
MRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U DkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPURExExEU8RbRGM
8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZ EaoRyRHoEgcSJhJFEmQShBKjEsMS4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTwFRIVNBVW
IBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkd FXgVmxW9FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkgGUUZaxmR
wx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i GbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzMHPUdHh1HHXAdmR3DHeweFh5A
3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8o HmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFIIXUhoSHOIfsiJyJVIoIiryLdIwojOCNm
cSiiKNQpBik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4WLkwu I5QjwiPwJB8kTSR8JKsk2iUJJTglaCWXJccl9yYnJlcmhya3JugnGCdJJ3onqyfcKA0oPyhxKKIo1CkG
gi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1 KTgpaymdKdAqAio1KmgqmyrPKwIrNitpK50r0SwFLDksbiyiLNctDC1BLXYtqy3hLhYuTC6CLrcu7i8k
EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuqO+g8 L1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUTNU01hzXC
JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31D Nf02NzZyNq426TckN2A3nDfXOBQ4UDiMOMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o76DwnPGU8pDzj
wEQDREdEikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL PSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/iQCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPARANER0SK
4kwqTHJMuk0CTUpNk03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJU RM5FEkVVRZpF3kYiRmdGq0bwRzVHe0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpMcky6
j1TbVShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhd TQJNSk2TTdxOJU5uTrdPAE9JT5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSPVNtVKFV1
yV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1n VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1kaWWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSddeF3JXhpebF69
k2fpaD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx Xw9fYV+zYAVgV2CqYPxhT2GiYfViSWKcYvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeTZ+loP2iW
8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF8 aOxpQ2maafFqSGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpxlXHwcktypnMB
4X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4efiASI c11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJeed6RnqlewR7Y3vCfCF8gXzhfUF9oX4B
aYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2lCCU fmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSDV4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhpiM6JM4mZ
ipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNih if6KZIrKizCLlov8jGOMyo0xjZiN/45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSKlPSVX5XJ
R6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2u ljSWn5cKl3WX4JhMmLiZJJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFHobaiJqKW
oa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8 owajdqPmpFakx6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6hrxavi7AA
m70VvY++Cr6Evv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfL sHWw6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6tbsuu6e8IbybvRW9j74K
Nsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHa voS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbDx0HHv8g9yLzJOsm5yjjKt8s2y7bMNcy1
dtr724DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDq zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp22vvbgNwF
W+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf6 3IrdEN2W3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3mlucf56noMui86Ubp0Opb6uXrcOv7
5/t3/Af8mP0p/br+S/7c/23//4AO0iUmSEldTlNNdXRhYmxlRGF0YaNISipWTlNEYXRh0iUmTE1cTlND 7IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe9m32+/eK+Bn4qPk4+cf6V/rn+3f8B/yY
b2xvclNwYWNlok4qXE5TQ29sb3JTcGFjZdIlJlBRV05TQ29sb3KiUCrSJSZTVFdOU0ltYWdlolMqXxAP /Sn9uv5L/tz/bf//0issS0xcTlNDb2xvclNwYWNlok0wXE5TQ29sb3JTcGFjZdIrLE9QV05TQ29sb3Ki
TlNLZXllZEFyY2hpdmVy0VdYVHJvb3SAAQAIABEAGgAjAC0AMgA3AEwAUgBdAGQAawB4AH8AhwCJAIsA TzDSKyxSU1dOU0ltYWdlolIwAAgAEQAaACQAKQAyADcASQBMAFEAUwBnAG0AegCBAJAAlwCkAKsAswC1
kACSAJQAnQCiAK0ArwCxALMAuAC7AL0AvwDBAMMAyADfAOEA4yAdICIgLSA2IEkgTSBYIGEgZiBuIHEg ALcAuQC+AMAAwgDLANAA2wDdAN8A4QDmAOkA6wDtAO8A9gENASkBKwEtIGcgbCB3IIAgkyCXIKIgqyCw
diCFIIkglCCcIKkgtiDLINAg1CDWINgg2iDjIOgg7iD2IPgg+iD8IP4hAyELMncyeTJ+MowykDKXMpwy ILgguyDAIM8g0yDeIOYg8yEAIRUhGiEeISAhIiEkIS0hMiE4IUAhQiFEIUYhSDLoMu0y+jL9MwozDzMX
qTKsMrkyvjLGMskyzjLWMtky6zLuMvMAAAAAAAACAQAAAAAAAABZAAAAAAAAAAAAAAAAAAAy9Q MxozHzMnAAAAAAAAAgEAAAAAAAAAVAAAAAAAAAAAAAAAAAAAMyo
</mutableData> </mutableData>
</image> </image>
<image name="call_hangup_default.png" width="67.199996948242188" height="58.400001525878906"/> <image name="call_hangup_default.png" width="67.199996948242188" height="58.400001525878906"/>
@ -1847,5 +1850,8 @@ qTKsMrkyvjLGMskyzjLWMtky6zLuMvMAAAAAAAACAQAAAAAAAABZAAAAAAAAAAAAAAAAAAAy9Q
<image name="speaker_disabled.png" width="44" height="41.599998474121094"/> <image name="speaker_disabled.png" width="44" height="41.599998474121094"/>
<image name="speaker_selected.png" width="44" height="41.599998474121094"/> <image name="speaker_selected.png" width="44" height="41.599998474121094"/>
<image name="waiting_time.png" width="96.800003051757812" height="115.19999694824219"/> <image name="waiting_time.png" width="96.800003051757812" height="115.19999694824219"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources> </resources>
</document> </document>

View file

@ -21,6 +21,7 @@
#import "UICallConferenceCell.h" #import "UICallConferenceCell.h"
#import "LinphoneManager.h" #import "LinphoneManager.h"
#import "Utils.h" #import "Utils.h"
#import "linphoneapp-Swift.h"
@implementation CallConferenceTableView @implementation CallConferenceTableView
@ -30,21 +31,6 @@
[self.tableView reloadData]; [self.tableView reloadData];
} }
#pragma mark - UITableViewDataSource Functions
- (LinphoneCall *)conferenceCallForRow:(NSInteger)row {
const MSList *calls = linphone_core_get_calls(LC);
int i = -1;
while (calls) {
if (linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(calls->data))) {
i++;
if (i == row)
break;
}
calls = calls->next;
}
return (calls ? calls->data : NULL);
}
#pragma mark - UITableViewDataSource Functions #pragma mark - UITableViewDataSource Functions
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@ -53,21 +39,16 @@
if (cell == nil) { if (cell == nil) {
cell = [[UICallConferenceCell alloc] initWithIdentifier:kCellId]; cell = [[UICallConferenceCell alloc] initWithIdentifier:kCellId];
} }
[cell setCall:[self conferenceCallForRow:indexPath.row]]; LinphoneConference *c = [CallManager.instance getConference];
cell.contentView.userInteractionEnabled = false; if (c != nil) {
[cell setParticipant:bctbx_list_nth_data(linphone_conference_get_participant_list(c),(int)indexPath.row)];
}
cell.contentView.userInteractionEnabled = NO;
return cell; return cell;
} }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
const MSList *calls = linphone_core_get_calls(LC); return [CallManager.instance getConference] ? linphone_conference_get_participant_count([CallManager.instance getConference]) : 0;
int count = 0;
while (calls) {
if (linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(calls->data))) {
count++;
}
calls = calls->next;
}
return count;
} }
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

View file

@ -45,6 +45,8 @@ import AVFoundation
var endCallkit: Bool = false var endCallkit: Bool = false
var globalState : GlobalState = .Off var globalState : GlobalState = .Off
var actionsToPerformOnceWhenCoreIsOn : [(()->Void)] = [] var actionsToPerformOnceWhenCoreIsOn : [(()->Void)] = []
var conference: Conference?
var backgroundContextCall : Call? var backgroundContextCall : Call?
@objc var backgroundContextCameraIsEnabled : Bool = false @objc var backgroundContextCameraIsEnabled : Bool = false
@ -137,27 +139,17 @@ import AVFoundation
} }
@objc func changeRouteToSpeaker() { @objc func changeRouteToSpeaker() {
for device in lc!.audioDevices { lc?.outputAudioDevice = lc?.audioDevices.first { $0.type == AudioDeviceType.Speaker }
if (device.type == AudioDeviceType.Speaker) {
lc!.outputAudioDevice = device
break
}
}
UIDevice.current.isProximityMonitoringEnabled = false UIDevice.current.isProximityMonitoringEnabled = false
} }
@objc func changeRouteToBluetooth() { @objc func changeRouteToBluetooth() {
for device in lc!.audioDevices { lc?.outputAudioDevice = lc?.audioDevices.first { $0.type == AudioDeviceType.BluetoothA2DP || $0.type == AudioDeviceType.Bluetooth }
if (device.type == AudioDeviceType.Bluetooth || device.type == AudioDeviceType.BluetoothA2DP) {
lc!.outputAudioDevice = device
break
}
}
UIDevice.current.isProximityMonitoringEnabled = (lc!.callsNb > 0) UIDevice.current.isProximityMonitoringEnabled = (lc!.callsNb > 0)
} }
@objc func changeRouteToDefault() { @objc func changeRouteToDefault() {
lc!.outputAudioDevice = lc!.defaultOutputAudioDevice lc?.outputAudioDevice = lc?.defaultOutputAudioDevice
} }
@objc func isBluetoothAvailable() -> Bool { @objc func isBluetoothAvailable() -> Bool {
@ -266,7 +258,7 @@ import AVFoundation
} }
let sAddr = Address.getSwiftObject(cObject: addr!) let sAddr = Address.getSwiftObject(cObject: addr!)
if (CallManager.callKitEnabled() && !CallManager.instance().nextCallIsTransfer) { if (CallManager.callKitEnabled() && !CallManager.instance().nextCallIsTransfer && !isInConference()) {
let uuid = UUID() let uuid = UUID()
let name = FastAddressBook.displayName(for: addr) ?? "unknow" let name = FastAddressBook.displayName(for: addr) ?? "unknow"
let handle = CXHandle(type: .generic, value: sAddr.asStringUriOnly()) let handle = CXHandle(type: .generic, value: sAddr.asStringUriOnly())
@ -475,6 +467,21 @@ import AVFoundation
CallManager.instance().endCallkit = false CallManager.instance().endCallkit = false
} }
} }
func onConferenceStateChanged(core: Core, conference: Conference, state: Conference.State) {
if (state == .Terminated) {
CallManager.instance().conference = nil
}
}
func onAudioDevicesListUpdated(core: Core) {
let bluetoothAvailable = isBluetoothAvailable();
var dict = Dictionary<String, Bool>()
dict["available"] = bluetoothAvailable
NotificationCenter.default.post(name: Notification.Name("LinphoneBluetoothAvailabilityUpdate"), object: self, userInfo: dict)
}
func onCallStateChanged(core: Core, call: Call, state cstate: Call.State, message: String) { func onCallStateChanged(core: Core, call: Call, state cstate: Call.State, message: String) {
let callLog = call.callLog let callLog = call.callLog
@ -626,9 +633,11 @@ import AVFoundation
} }
if (cstate == .IncomingReceived || cstate == .OutgoingInit || cstate == .Connected || cstate == .StreamsRunning) { if (cstate == .IncomingReceived || cstate == .OutgoingInit || cstate == .Connected || cstate == .StreamsRunning) {
let check = call.currentParams?.videoEnabled
if ((call.currentParams?.videoEnabled ?? false) && CallManager.instance().isReceiverEnabled()) { if ((call.currentParams?.videoEnabled ?? false) && CallManager.instance().isReceiverEnabled()) {
CallManager.instance().changeRouteToSpeaker() CallManager.instance().changeRouteToSpeaker()
} else if (isBluetoothAvailable()) {
// Use bluetooth device by default if one is available
CallManager.instance().changeRouteToBluetooth()
} }
} }
} }
@ -639,6 +648,116 @@ import AVFoundation
AnyHashable("message"): message AnyHashable("message"): message
]) ])
} }
// Conference
@objc func hostConference() -> Bool {
return conference != nil
}
func addAllToConference() {
if (conference == nil) {
guard let cp = try?lc?.createConferenceParams() else {
Log.directLog(BCTBX_LOG_ERROR, text: "Unable to create conference parameters")
return
}
if let currentCall = lc?.currentCall, let currentParams = currentCall.currentParams {
cp.videoEnabled = currentParams.videoEnabled
}
conference = try?lc?.createConferenceWithParams(params: cp)
}
lc?.calls.forEach { call in
if (call.conference == nil || call.conference?.participantCount == 1) {
try?conference?.addParticipant(call: call)
}
}
}
@objc func getConference() -> OpaquePointer? {
guard let core = lc else {
return nil
}
return (core.conference != nil) ? core.conference?.getCobject : (core.currentCall?.conference != nil) ? core.currentCall!.conference!.getCobject : nil
}
func getConference() -> Conference? {
guard let core = lc else {
return nil
}
return (core.conference != nil) ? core.conference : (core.currentCall?.conference != nil) ? core.currentCall!.conference : nil
}
@objc func isInConference() -> Bool {
return isInConferenceAsHost()||isInConferenceAsGuest()
}
@objc func isInConferenceAsGuest() -> Bool {
guard let core = lc else {
return false
}
return !isInConferenceAsHost() && core.currentCall != nil && core.currentCall?.conference != nil && (core.currentCall?.conference!.participantCount)! > 1
}
@objc func isInConferenceAsHost() -> Bool {
guard let core = lc else {
return false
}
return core.conference?.isIn == true
}
@objc func hasConferenceAsGuest() -> Bool {
guard let core = lc else {
return false
}
if (core.callsNb<=1) {
return false
}
var found = false
core.calls.forEach {
let c = $0.conference
if (c != nil && c!.participantCount > 1 && hostConference()) {
found = true
return
}
}
return found
}
@objc func getCallFor(participant : OpaquePointer) -> OpaquePointer? {
let p = Participant.getSwiftObject(cObject: participant)
guard let core = lc else {
return nil
}
var call:Call? = nil
core.calls.forEach { (callIt) in
let c = callIt.conference
c?.participantList.forEach { (p2) in
if (p2.address?.asStringUriOnly() == p.address?.asStringUriOnly()) {
call = callIt
return
}
}
}
return call?.getCobject
}
@objc func inVideoConf() -> Bool {
guard let core = lc else {
return false
}
return isInConference() && (getConference()?.currentParams?.isVideoEnabled == true || core.currentCall?.currentParams?.videoEnabled == true)
}
@objc func inAudioConf() -> Bool {
guard let core = lc else {
return false
}
return core.conference?.isIn == true && core.conference != nil && core.currentCall?.conference?.currentParams?.isVideoEnabled == false
}
} }

View file

@ -99,7 +99,7 @@ static UICompositeViewDescription *compositeDescription = nil;
ms_free(uri); ms_free(uri);
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES]; [_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
[self hideSpeaker:LinphoneManager.instance.bluetoothAvailable]; [self hideSpeaker: [CallManager.instance isBluetoothAvailable]];
[_speakerButton update]; [_speakerButton update];
[_microButton update]; [_microButton update];

View file

@ -24,6 +24,7 @@
#import <QuartzCore/CAAnimation.h> #import <QuartzCore/CAAnimation.h>
#import <QuartzCore/QuartzCore.h> #import <QuartzCore/QuartzCore.h>
#import <UserNotifications/UserNotifications.h> #import <UserNotifications/UserNotifications.h>
#import "UICallConferenceCell.h"
#import "CallView.h" #import "CallView.h"
#import "CallSideMenuView.h" #import "CallSideMenuView.h"
@ -147,7 +148,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[self hideRoutes:TRUE animated:FALSE]; [self hideRoutes:TRUE animated:FALSE];
[self hideOptions:TRUE animated:FALSE]; [self hideOptions:TRUE animated:FALSE];
[self hidePad:TRUE animated:FALSE]; [self hidePad:TRUE animated:FALSE];
[self hideSpeaker:LinphoneManager.instance.bluetoothAvailable]; [self hideSpeaker: [CallManager.instance isBluetoothAvailable]];
[self callDurationUpdate]; [self callDurationUpdate];
[self onCurrentCallChange]; [self onCurrentCallChange];
// Set windows (warn memory leaks) // Set windows (warn memory leaks)
@ -170,12 +171,25 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(callUpdateEvent:) selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate name:kLinphoneCallUpdate
object:nil]; object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(participantListChanged:)
name:kLinphoneConfStateParticipantListChanged
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(confStateChanged:)
name:kLinphoneConfStateChanged
object:nil];
[NSTimer scheduledTimerWithTimeInterval:1 [NSTimer scheduledTimerWithTimeInterval:1
target:self target:self
selector:@selector(callDurationUpdate) selector:@selector(callDurationUpdate)
userInfo:nil userInfo:nil
repeats:YES]; repeats:YES];
} }
- (void)viewDidAppear:(BOOL)animated { - (void)viewDidAppear:(BOOL)animated {
@ -263,7 +277,8 @@ static UICompositeViewDescription *compositeDescription = nil;
_pausedByRemoteView.hidden = NO; _pausedByRemoteView.hidden = NO;
[self updateInfoView:TRUE]; [self updateInfoView:TRUE];
} }
_conferenceView.hidden = !linphone_core_is_in_conference(LC); _conferenceView.hidden = ![CallManager.instance isInConference];
[self onCurrentCallChange];
} }
#pragma mark - UI modification #pragma mark - UI modification
@ -312,9 +327,8 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
_optionsButton.enabled = (!call || !linphone_core_sound_resources_locked(LC)); _optionsButton.enabled = (!call || !linphone_core_sound_resources_locked(LC));
_optionsTransferButton.enabled = call && !linphone_core_sound_resources_locked(LC); _optionsTransferButton.enabled = call && !linphone_core_sound_resources_locked(LC);
// enable conference button if 2 calls are presents and at least one is not in the conference // enable conference button if 2 calls are presents and at least one is not in the conference
int confSize = linphone_core_get_conference_size(LC) - (linphone_core_is_in_conference(LC) ? 1 : 0); int confSize = linphone_core_get_conference_size(LC) - ([CallManager.instance isInConference] ? 1 : 0);
_optionsConferenceButton.enabled = _optionsConferenceButton.enabled = (linphone_core_get_calls_nb(LC) > 1) && (linphone_core_get_calls_nb(LC) != confSize) && !CallManager.instance.hasConferenceAsGuest;
((linphone_core_get_calls_nb(LC) > 1) && (linphone_core_get_calls_nb(LC) != confSize));
// Disable transfert in conference // Disable transfert in conference
if (linphone_core_get_current_call(LC) == NULL) { if (linphone_core_get_current_call(LC) == NULL) {
@ -359,8 +373,18 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[UIView beginAnimations:nil context:nil]; [UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.35]; [UIView setAnimationDuration:0.35];
_pausedCallsTable.tableView.alpha = _videoCameraSwitch.alpha = _callPauseButton.alpha = _routesView.alpha = _pausedCallsTable.tableView.alpha = _videoCameraSwitch.alpha = _callPauseButton.alpha = _routesView.alpha =
_optionsView.alpha = _numpadView.alpha = _bottomBar.alpha = (hidden ? 0 : 1); _optionsView.alpha = _numpadView.alpha = _bottomBar.alpha = _conferenceView.alpha = (hidden ? 0 : 1);
_infoView.alpha = (hidden ? 0 : .8f); _infoView.alpha = (hidden ? 0 : .8f);
if ([CallManager.instance inVideoConf]) {
_videoCameraSwitch.frame = CGRectMake(_videoCameraSwitch.frame.origin.x, _bottomBar.frame.origin.y - 75, _videoCameraSwitch.frame.size.width,_videoCameraSwitch.frame.size.height);
}
if (CallManager.instance.isInConference) {
_callPauseButton.hidden = true;
_conferenceView.frame = CGRectMake(_conferenceView.frame.origin.x,_conferenceView.frame.origin.y,_conferenceView.frame.size.width,_conferenceCallsTable.tableView.frame.origin.y+[_conferenceCallsTable.tableView numberOfRowsInSection:0]*CONFERENCE_CELL_HEIGHT+10);
}
[UIView commitAnimations]; [UIView commitAnimations];
@ -426,12 +450,25 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[_videoWaitingForFirstImage setHidden:NO]; [_videoWaitingForFirstImage setHidden:NO];
[_videoWaitingForFirstImage startAnimating]; [_videoWaitingForFirstImage startAnimating];
LinphoneCall *call = linphone_core_get_current_call(LC); if ([CallManager.instance inVideoConf])
// linphone_call_params_get_used_video_codec return 0 if no video stream enabled [self hideSpinnerIndicator:nil];
if (call != NULL && linphone_call_params_get_used_video_codec(linphone_call_get_current_params(call))) { else {
linphone_call_set_next_video_frame_decoded_callback(call, hideSpinner, (__bridge void *)(self)); LinphoneCall *call = linphone_core_get_current_call(LC);
// linphone_call_params_get_used_video_codec return 0 if no video stream enabled
if (call != NULL && linphone_call_params_get_used_video_codec(linphone_call_get_current_params(call))) {
linphone_call_set_next_video_frame_decoded_callback(call, hideSpinner, (__bridge void *)(self));
}
} }
} }
if ([CallManager.instance isInConference]) {
[_conferenceView removeFromSuperview];
[_callView addSubview:_conferenceView];
} else {
[_conferenceView removeFromSuperview];
[self.view addSubview:_conferenceView];
[self.view sendSubviewToBack:_conferenceView];
}
} }
- (void)displayVideoCall:(BOOL)animated { - (void)displayVideoCall:(BOOL)animated {
@ -454,15 +491,17 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
- (void)onCurrentCallChange { - (void)onCurrentCallChange {
LinphoneCall *call = linphone_core_get_current_call(LC); LinphoneCall *call = linphone_core_get_current_call(LC);
_noActiveCallView.hidden = (call || linphone_core_is_in_conference(LC)); _noActiveCallView.hidden = (call || CallManager.instance.isInConference);
_callView.hidden = !call; _callView.hidden = !call && !CallManager.instance.isInConference;
_conferenceView.hidden = !linphone_core_is_in_conference(LC); _conferenceView.hidden = !CallManager.instance.isInConference;
_callPauseButton.hidden = !call && !linphone_core_is_in_conference(LC); _conferenceView.hidden = !CallManager.instance.isInConference;
_callPauseButton.hidden = !call;
[_callPauseButton setType:UIPauseButtonType_CurrentCall call:call]; [_callPauseButton setType:UIPauseButtonType_CurrentCall call:call];
[_conferencePauseButton setType:UIPauseButtonType_Conference call:call]; [_conferencePauseButton setType:UIPauseButtonType_Conference call:call];
if (!_callView.hidden) { if (call) {
const LinphoneAddress *addr = linphone_call_get_remote_address(call); const LinphoneAddress *addr = linphone_call_get_remote_address(call);
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr];
char *uri = linphone_address_as_string_uri_only(addr); char *uri = linphone_address_as_string_uri_only(addr);
@ -551,19 +590,13 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
// Update tables // Update tables
[_pausedCallsTable update]; [_pausedCallsTable update];
[_conferenceCallsTable update]; [_conferenceCallsTable update];
static LinphoneCall *currentCall = NULL; [self onCurrentCallChange];
if (!currentCall || linphone_core_get_current_call(LC) != currentCall) {
currentCall = linphone_core_get_current_call(LC); LinphoneCall *currentCall = linphone_core_get_current_call(LC);
[self onCurrentCallChange]; BOOL shouldDisableVideo = currentCall ? !linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall)): ![CallManager.instance inVideoConf];
}
// Fake call update
if (call == NULL) {
return;
}
BOOL shouldDisableVideo = !currentCall || !linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall));
if (videoHidden != shouldDisableVideo) { if (videoHidden != shouldDisableVideo) {
if (!shouldDisableVideo) { if (!shouldDisableVideo) {
[self displayVideoCall:animated]; [self displayVideoCall:animated];
@ -571,12 +604,11 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[self displayAudioCall:animated]; [self displayAudioCall:animated];
} }
} }
if (!shouldDisableVideo && !linphone_core_is_in_conference(LC) && // camera is diabled duiring conference, it must be activated after leaving conference. // Fake call update
[UIApplication sharedApplication].applicationState == UIApplicationStateActive) { // Camera should not be enabled when in background) if (call == NULL) {
linphone_call_enable_camera(call, TRUE); return;
} }
[self updateCallView];
if (state != LinphoneCallPausedByRemote) { if (state != LinphoneCallPausedByRemote) {
_pausedByRemoteView.hidden = YES; _pausedByRemoteView.hidden = YES;
@ -623,7 +655,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max))) { floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max))) {
linphone_core_defer_call_update(LC, call); linphone_core_defer_call_update(LC, call);
[self displayAskToEnableVideoCall:call]; [self displayAskToEnableVideoCall:call];
} else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { } else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote) && ![CallManager.instance inVideoConf]) {
[self displayAudioCall:animated]; [self displayAudioCall:animated];
} }
break; break;
@ -633,10 +665,12 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[self displayAudioCall:animated]; [self displayAudioCall:animated];
break; break;
case LinphoneCallPausedByRemote: case LinphoneCallPausedByRemote:
[self displayAudioCall:animated]; if (![CallManager.instance inVideoConf]) {
if (call == linphone_core_get_current_call(LC)) { [self displayAudioCall:animated];
_pausedByRemoteView.hidden = NO; if (call == linphone_core_get_current_call(LC)) {
[self updateInfoView:TRUE]; _pausedByRemoteView.hidden = NO;
[self updateInfoView:TRUE];
}
} }
break; break;
case LinphoneCallEnd: case LinphoneCallEnd:
@ -651,7 +685,13 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
- (void)displayAskToEnableVideoCall:(LinphoneCall *)call { - (void)displayAskToEnableVideoCall:(LinphoneCall *)call {
if (linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call))) { if (linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call))) {
return; return;
} else if (CallManager.instance.inVideoConf) {
LinphoneCallParams *params = linphone_core_create_call_params(LC, call);
linphone_call_params_enable_video(params, TRUE);
linphone_call_accept_update(call, params);
return;
} }
if (linphone_core_get_video_policy(LC)->automatically_accept && if (linphone_core_get_video_policy(LC)->automatically_accept &&
!([UIApplication sharedApplication].applicationState != UIApplicationStateActive)) !([UIApplication sharedApplication].applicationState != UIApplicationStateActive))
return; return;
@ -825,6 +865,9 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
} }
- (IBAction)onOptionsClick:(id)sender { - (IBAction)onOptionsClick:(id)sender {
int confSize = linphone_core_get_conference_size(LC) - (CallManager.instance.isInConference ? 1 : 0);
_optionsConferenceButton.enabled = (linphone_core_get_calls_nb(LC) > 1) && (linphone_core_get_calls_nb(LC) != confSize) && !CallManager.instance.hasConferenceAsGuest;
if ([_optionsView isHidden]) { if ([_optionsView isHidden]) {
[self hideOptions:FALSE animated:ANIMATED]; [self hideOptions:FALSE animated:ANIMATED];
} else { } else {
@ -909,4 +952,56 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[_chatNotificationView stopAnimating:appear]; [_chatNotificationView stopAnimating:appear];
} }
} }
#pragma mark - Conference
- (void)participantListChanged:(NSNotification *)notif {
[self confStateChanged:nil];
[_conferenceCallsTable update];
_conferenceView.frame = CGRectMake(_conferenceView.frame.origin.x,_conferenceView.frame.origin.y,_conferenceView.frame.size.width,_conferenceCallsTable.tableView.frame.origin.y+[_conferenceCallsTable.tableView numberOfRowsInSection:0]*CONFERENCE_CELL_HEIGHT+10);
[self onCurrentCallChange];
_conferenceView.hidden = !CallManager.instance.isInConference;
}
- (void)confStateChanged:(NSNotification *)notif {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if ([CallManager.instance inVideoConf]) {
[self displayVideoCall:true];
} else if (CallManager.instance.isInConference) {
[self displayAudioConference];
} else {
[self displayAudioCall:true];
_callPauseButton.hidden = NO;
_nameLabel.hidden = NO;
_durationLabel.hidden = NO;
_avatarImage.hidden = NO;
}
[_conferenceCallsTable update];
_conferenceView.frame = CGRectMake(_conferenceView.frame.origin.x,_conferenceView.frame.origin.y,_conferenceView.frame.size.width,_conferenceCallsTable.tableView.frame.origin.y+[_conferenceCallsTable.tableView numberOfRowsInSection:0]*CONFERENCE_CELL_HEIGHT+10);
});
}
-(void) displayAudioConference {
_callPauseButton.hidden = true;
_nameLabel.hidden = true;
_conferenceView.frame = CGRectMake(_conferenceView.frame.origin.x,_conferenceView.frame.origin.y,_conferenceView.frame.size.width,_conferenceCallsTable.tableView.frame.origin.y+[_conferenceCallsTable.tableView numberOfRowsInSection:0]*CONFERENCE_CELL_HEIGHT+10);
_durationLabel.hidden = true;
_avatarImage.hidden = true;
[_conferenceView removeFromSuperview];
[_callView addSubview:_conferenceView];
if ([CallManager.instance isInConference]) {
[_conferenceView removeFromSuperview];
[_callView addSubview:_conferenceView];
_conferenceView.hidden = NO;
} else {
[_conferenceView removeFromSuperview];
[self.view addSubview:_conferenceView];
[self.view sendSubviewToBack:_conferenceView];
}
}
@end @end

View file

@ -95,9 +95,9 @@
+ (void)markAsRead:(LinphoneChatRoom *)chatRoom; + (void)markAsRead:(LinphoneChatRoom *)chatRoom;
+ (void)autoDownload:(LinphoneChatMessage *)message; + (void)autoDownload:(LinphoneChatMessage *)message;
+(NSString *)getKeyFromFileType:(NSString *)fileType fileName:(NSString *)name; +(NSString *)getKeyFromFileType:(NSString *)fileType fileName:(NSString *)name;
+ (NSURL *)getFileUrl:(NSString *)name; + (NSURL *)getCacheFileUrl:(NSString *)name;
+ (void)writeFileInImagesDirectory:(NSData *)data name:(NSString *)name; + (void)writeFileInCache:(NSData *)data name:(NSString *)name;
+ (NSData *)getFileData:(NSString *)name; + (NSData *)getCacheFileData:(NSString *)name;
+ (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType; + (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType;
+(UIImage *)getBasicImage; +(UIImage *)getBasicImage;
+(UIImage*)drawText:(NSString*)text image:(UIImage *)image textSize:(CGFloat)textSize; +(UIImage*)drawText:(NSString*)text image:(UIImage *)image textSize:(CGFloat)textSize;
@ -121,6 +121,7 @@
- (void)showFileDownloadError; - (void)showFileDownloadError;
- (NSURL *)getICloudFileUrl:(NSString *)name; - (NSURL *)getICloudFileUrl:(NSString *)name;
- (BOOL)writeFileInICloud:(NSData *)data fileURL:(NSURL *)fileURL;
- (void)removeCallBacks; - (void)removeCallBacks;
@end @end

View file

@ -901,7 +901,7 @@ static UICompositeViewDescription *compositeDescription = nil;
} }
+ (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType { + (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType {
NSString *filePath = [LinphoneManager validFilePath:name]; NSString *filePath = [LinphoneManager getValidFile:name];
NSFileManager *fileManager = [NSFileManager defaultManager]; NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filePath]) { if ([fileManager fileExistsAtPath:filePath]) {
NSData* data = [NSData dataWithContentsOfFile:filePath]; NSData* data = [NSData dataWithContentsOfFile:filePath];
@ -1324,18 +1324,18 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
[PhoneMainView.instance fullScreen:NO]; [PhoneMainView.instance fullScreen:NO];
} }
+ (NSData *)getFileData: (NSString *)name { + (NSData *)getCacheFileData: (NSString *)name {
NSString *filePath = [LinphoneManager validFilePath:name]; NSString *filePath = [LinphoneManager getValidFile:name];
return [NSData dataWithContentsOfFile:filePath]; return [NSData dataWithContentsOfFile:filePath];
} }
+ (NSURL *)getFileUrl: (NSString *)name { + (NSURL *)getCacheFileUrl: (NSString *)name {
NSString *filePath = [LinphoneManager validFilePath:name]; NSString *filePath = [LinphoneManager getValidFile:name];
return [NSURL fileURLWithPath:filePath]; return [NSURL fileURLWithPath:filePath];
} }
+ (void)writeFileInImagesDirectory:(NSData *)data name:(NSString *)name { + (void)writeFileInCache:(NSData *)data name:(NSString *)name {
NSString *filePath = [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name]; NSString *filePath =[LinphoneManager getValidFile:name];
if (name || [name isEqualToString:@""]) { if (name || [name isEqualToString:@""]) {
LOGW(@"try to write file in %@", filePath); LOGW(@"try to write file in %@", filePath);
} }
@ -1364,6 +1364,44 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
return nil; return nil;
} }
- (BOOL)writeFileInICloud:(NSData *)data fileURL:(NSURL *)fileURL {
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL useMyDevice = FALSE;
if (@available(iOS 11.0, *)) {
useMyDevice = TRUE;
}
if (!useMyDevice && ![[fileManager URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]) {
//notify : set configuration to use icloud
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Info", nil) message:NSLocalizedString(@"ICloud Drive is unavailable.", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:nil, nil] show];
return FALSE;
}
NSString *fileName = fileURL.lastPathComponent;
if ([fileManager fileExistsAtPath:[fileURL path]] || [fileName hasPrefix:@"recording"]) {
// if it exists, replace the file. If it's a record file, copy the file
return [data writeToURL:fileURL atomically:TRUE];
} else {
// get the url of localfile
NSString *filePath = [LinphoneManager getValidFile:fileName];
NSURL *localURL = nil;
if (fileName || [fileName isEqualToString:@""]) {
LOGW(@"[writeFileInICloud] try to write file in %@", filePath);
}
if ([fileManager createFileAtPath:filePath contents:data attributes:nil]) {
localURL = [NSURL fileURLWithPath:filePath];
}
NSError *error;
if ([[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:fileURL error:&error]) {
return TRUE;
} else {
LOGE(@"Cannot write file in Icloud file [%@]",[error localizedDescription]);
return FALSE;
}
}
}
- (void)deleteFileWithUuid:(NSUUID *)uuid { - (void)deleteFileWithUuid:(NSUUID *)uuid {
[_fileContext deleteContentWithUuid:uuid]; [_fileContext deleteContentWithUuid:uuid];
[self refreshImageDrawer]; [self refreshImageDrawer];

View file

@ -202,15 +202,19 @@
[self setCString:tmp forKey:@"account_proxy_preference"]; [self setCString:tmp forKey:@"account_proxy_preference"];
} }
const char *tname = "udp"; const char *tname = "udp";
switch (linphone_address_get_transport(proxy_addr)) { if (linphone_address_get_secure(proxy_addr)) {
case LinphoneTransportTcp: tname = "tls";
tname = "tcp"; } else {
break; switch (linphone_address_get_transport(proxy_addr)) {
case LinphoneTransportTls: case LinphoneTransportTcp:
tname = "tls"; tname = "tcp";
break; break;
default: case LinphoneTransportTls:
break; tname = "tls";
break;
default:
break;
}
} }
linphone_address_unref(proxy_addr); linphone_address_unref(proxy_addr);
[self setCString:tname forKey:@"account_transport_preference"]; [self setCString:tname forKey:@"account_transport_preference"];
@ -495,6 +499,7 @@
NSString *userID = [self stringForKey:@"account_userid_preference"]; NSString *userID = [self stringForKey:@"account_userid_preference"];
NSString *domain = [self stringForKey:@"account_mandatory_domain_preference"]; NSString *domain = [self stringForKey:@"account_mandatory_domain_preference"];
NSString *transport = [self stringForKey:@"account_transport_preference"]; NSString *transport = [self stringForKey:@"account_transport_preference"];
BOOL isTransportTls = [transport isEqualToString:@"tls"];
NSString *accountHa1 = [self stringForKey:@"ha1_preference"]; NSString *accountHa1 = [self stringForKey:@"ha1_preference"];
NSString *accountPassword = [self stringForKey:@"account_mandatory_password_preference"]; NSString *accountPassword = [self stringForKey:@"account_mandatory_password_preference"];
NSString *accountAlgoPreference = [self stringForKey:@"ha1_algo_preference"]; NSString *accountAlgoPreference = [self stringForKey:@"ha1_algo_preference"];
@ -515,8 +520,12 @@
proxyAddress = domain; proxyAddress = domain;
} }
if (![proxyAddress hasPrefix:@"sip:"] && ![proxyAddress hasPrefix:@"sips:"]) { if (![proxyAddress hasPrefix:@"sip:"] && ![proxyAddress hasPrefix:@"sips:"]) {
proxyAddress = [NSString stringWithFormat:@"sip:%@", proxyAddress]; if (isTransportTls) {
proxyAddress = [NSString stringWithFormat:@"sips:%@", proxyAddress];
} else {
proxyAddress = [NSString stringWithFormat:@"sip:%@", proxyAddress];
}
} }
LinphoneAddress *proxy_addr = linphone_core_interpret_url(LC, proxyAddress.UTF8String); LinphoneAddress *proxy_addr = linphone_core_interpret_url(LC, proxyAddress.UTF8String);
@ -525,7 +534,7 @@
LinphoneTransportType type = LinphoneTransportUdp; LinphoneTransportType type = LinphoneTransportUdp;
if ([transport isEqualToString:@"tcp"]) if ([transport isEqualToString:@"tcp"])
type = LinphoneTransportTcp; type = LinphoneTransportTcp;
else if ([transport isEqualToString:@"tls"]) else if (isTransportTls)
type = LinphoneTransportTls; type = LinphoneTransportTls;
linphone_address_set_transport(proxy_addr, type); linphone_address_set_transport(proxy_addr, type);
@ -538,8 +547,9 @@
if (account == NULL) if (account == NULL)
goto bad_proxy; goto bad_proxy;
LinphoneAddress *linphoneAddress = linphone_core_interpret_url(LC, "sip:user@domain.com"); LinphoneAddress *linphoneAddress;
linphoneAddress = linphone_core_interpret_url(LC, "sip:user@domain.com");
linphone_address_set_username(linphoneAddress, username.UTF8String); linphone_address_set_username(linphoneAddress, username.UTF8String);
if ([LinphoneManager.instance lpConfigBoolForKey:@"use_phone_number" inSection:@"assistant"]) { if ([LinphoneManager.instance lpConfigBoolForKey:@"use_phone_number" inSection:@"assistant"]) {
char *user = linphone_account_normalize_phone_number(account, username.UTF8String); char *user = linphone_account_normalize_phone_number(account, username.UTF8String);

View file

@ -60,6 +60,9 @@ extern NSString *const kLinphoneFileTransferRecvUpdate;
extern NSString *const kLinphoneQRCodeFound; extern NSString *const kLinphoneQRCodeFound;
extern NSString *const kLinphoneChatCreateViewChange; extern NSString *const kLinphoneChatCreateViewChange;
extern NSString *const kLinphoneEphemeralMessageDeletedInRoom; extern NSString *const kLinphoneEphemeralMessageDeletedInRoom;
extern NSString *const kLinphoneConfStateParticipantListChanged;
extern NSString *const kLinphoneConfStateChanged;
extern NSString *const kLinphoneMsgNotificationAppGroupId; extern NSString *const kLinphoneMsgNotificationAppGroupId;
@ -132,8 +135,7 @@ typedef struct _LinphoneManagerSounds {
+ (NSString *)documentFile:(NSString *)file; + (NSString *)documentFile:(NSString *)file;
+ (NSString*)dataFile:(NSString*)file; + (NSString*)dataFile:(NSString*)file;
+ (NSString*)cacheDirectory; + (NSString*)cacheDirectory;
+ (NSString *)imagesDirectory; + (NSString *)getValidFile:(NSString *)name;
+ (NSString *)validFilePath:(NSString *)name;
// migration // migration
+ (NSString *)oldPreferenceFile:(NSString *)file; + (NSString *)oldPreferenceFile:(NSString *)file;
+ (NSString *)oldDataFile:(NSString *)file; + (NSString *)oldDataFile:(NSString *)file;
@ -186,6 +188,8 @@ typedef struct _LinphoneManagerSounds {
- (void)setupGSMInteraction; - (void)setupGSMInteraction;
- (BOOL)isCTCallCenterExist; - (BOOL)isCTCallCenterExist;
- (void) checkLocalNetworkPermission;
@property (readonly) BOOL isTesting; @property (readonly) BOOL isTesting;
@property(readonly, strong) FastAddressBook *fastAddressBook; @property(readonly, strong) FastAddressBook *fastAddressBook;
@ -196,7 +200,6 @@ typedef struct _LinphoneManagerSounds {
@property (readonly) sqlite3* database; @property (readonly) sqlite3* database;
@property (readonly) LinphoneManagerSounds sounds; @property (readonly) LinphoneManagerSounds sounds;
@property (readonly) NSMutableArray *logs; @property (readonly) NSMutableArray *logs;
@property (nonatomic, assign) BOOL bluetoothAvailable;
@property (readonly) NSString* contactSipField; @property (readonly) NSString* contactSipField;
@property (readonly,copy) NSString* contactFilter; @property (readonly,copy) NSString* contactFilter;
@property (copy) void (^silentPushCompletion)(UIBackgroundFetchResult); @property (copy) void (^silentPushCompletion)(UIBackgroundFetchResult);

View file

@ -75,7 +75,8 @@ NSString *const kLinphoneFileTransferRecvUpdate = @"LinphoneFileTransferRecvUpda
NSString *const kLinphoneQRCodeFound = @"LinphoneQRCodeFound"; NSString *const kLinphoneQRCodeFound = @"LinphoneQRCodeFound";
NSString *const kLinphoneChatCreateViewChange = @"LinphoneChatCreateViewChange"; NSString *const kLinphoneChatCreateViewChange = @"LinphoneChatCreateViewChange";
NSString *const kLinphoneEphemeralMessageDeletedInRoom = @"LinphoneEphemeralMessageDeletedInRoom"; NSString *const kLinphoneEphemeralMessageDeletedInRoom = @"LinphoneEphemeralMessageDeletedInRoom";
NSString *const kLinphoneConfStateChanged = @"kLinphoneConfStateChanged";
NSString *const kLinphoneConfStateParticipantListChanged = @"kLinphoneConfStateParticipantListChanged";
NSString *const kLinphoneMsgNotificationAppGroupId = @"group.org.linphone.phone.msgNotification"; NSString *const kLinphoneMsgNotificationAppGroupId = @"group.org.linphone.phone.msgNotification";
@ -230,10 +231,6 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
- (id)init { - (id)init {
if ((self = [super init])) { if ((self = [super init])) {
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(audioRouteChangeListenerCallback:)
name:AVAudioSessionRouteChangeNotification
object:nil];
NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"]; NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
self.messagePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil]; self.messagePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil];
@ -252,9 +249,6 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre
[self renameDefaultSettings]; [self renameDefaultSettings];
[self copyDefaultSettings]; [self copyDefaultSettings];
[self overrideDefaultSettings]; [self overrideDefaultSettings];
if (![self lpConfigBoolForKey:@"migration_images_done" withDefault:FALSE]) {
[self migrationAllImages];
}
[self lpConfigSetString:[LinphoneManager dataFile:@"linphone.db"] forKey:@"uri" inSection:@"storage"]; [self lpConfigSetString:[LinphoneManager dataFile:@"linphone.db"] forKey:@"uri" inSection:@"storage"];
[self lpConfigSetString:[LinphoneManager dataFile:@"x3dh.c25519.sqlite3"] forKey:@"x3dh_db_path" inSection:@"lime"]; [self lpConfigSetString:[LinphoneManager dataFile:@"x3dh.c25519.sqlite3"] forKey:@"x3dh_db_path" inSection:@"lime"];
@ -1374,6 +1368,8 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
linphone_core_cbs_set_call_id_updated(cbs, linphone_iphone_call_id_updated); linphone_core_cbs_set_call_id_updated(cbs, linphone_iphone_call_id_updated);
linphone_core_cbs_set_user_data(cbs, (__bridge void *)(self)); linphone_core_cbs_set_user_data(cbs, (__bridge void *)(self));
linphone_core_cbs_set_chat_room_ephemeral_message_deleted(cbs, linphone_iphone_ephemeral_message_deleted); linphone_core_cbs_set_chat_room_ephemeral_message_deleted(cbs, linphone_iphone_ephemeral_message_deleted);
linphone_core_cbs_set_conference_state_changed(cbs, linphone_iphone_conference_state_changed);
theLinphoneCore = linphone_factory_create_shared_core_with_config(factory, _configDb, NULL, [kLinphoneMsgNotificationAppGroupId UTF8String], true); theLinphoneCore = linphone_factory_create_shared_core_with_config(factory, _configDb, NULL, [kLinphoneMsgNotificationAppGroupId UTF8String], true);
@ -1403,7 +1399,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
/* Use the rootca from framework, which is already set*/ /* Use the rootca from framework, which is already set*/
//linphone_core_set_root_ca(theLinphoneCore, [LinphoneManager bundleFile:@"rootca.pem"].UTF8String); //linphone_core_set_root_ca(theLinphoneCore, [LinphoneManager bundleFile:@"rootca.pem"].UTF8String);
linphone_core_set_user_certificates_path(theLinphoneCore, linphone_factory_get_data_dir(linphone_factory_get(), kLinphoneMsgNotificationAppGroupId.UTF8String)); linphone_core_set_user_certificates_path(theLinphoneCore, [LinphoneManager cacheDirectory].UTF8String);
/* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded /* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded
(or skipped). (or skipped).
@ -1437,13 +1433,6 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
linphone_core_destroy(theLinphoneCore); linphone_core_destroy(theLinphoneCore);
LOGI(@"Destroy linphonecore %p", theLinphoneCore); LOGI(@"Destroy linphonecore %p", theLinphoneCore);
theLinphoneCore = nil; theLinphoneCore = nil;
// Post event
NSDictionary *dict =
[NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"];
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCoreUpdate
object:LinphoneManager.instance
userInfo:dict];
} }
libStarted = FALSE; libStarted = FALSE;
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
@ -1671,17 +1660,6 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
linphone_core_refresh_registers(theLinphoneCore); // just to make sure REGISTRATION is up to date linphone_core_refresh_registers(theLinphoneCore); // just to make sure REGISTRATION is up to date
} }
- (void)migrationAllImages {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *images = [fileManager contentsOfDirectoryAtPath:[LinphoneManager cacheDirectory] error:NULL];
for (NSString *image in images)
{
[fileManager copyItemAtPath:[[LinphoneManager cacheDirectory] stringByAppendingPathComponent:image] toPath:[[LinphoneManager imagesDirectory] stringByAppendingPathComponent:image] error:nil];
}
[self lpConfigSetBool:TRUE forKey:@"migration_images_done"];
}
- (void)migrateImportantFiles { - (void)migrateImportantFiles {
if ([LinphoneManager copyFile:[LinphoneManager oldPreferenceFile:@"linphonerc"] destination:[LinphoneManager preferenceFile:@"linphonerc"] override:TRUE ignore:TRUE]) { if ([LinphoneManager copyFile:[LinphoneManager oldPreferenceFile:@"linphonerc"] destination:[LinphoneManager preferenceFile:@"linphonerc"] override:TRUE ignore:TRUE]) {
[NSFileManager.defaultManager [NSFileManager.defaultManager
@ -1760,27 +1738,52 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
} }
#pragma mark - Audio route Functions #pragma mark - Audio route Functions
- (void)audioRouteChangeListenerCallback:(NSNotification *)notif {
if (IPAD)
return;
_bluetoothAvailable = [CallManager.instance isBluetoothAvailable];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:_bluetoothAvailable], @"available", nil];
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneBluetoothAvailabilityUpdate
object:self
userInfo:dict];
}
#pragma mark - Call Functions #pragma mark - Call Functions
- (void)send:(NSString *)replyText toChatRoom:(LinphoneChatRoom *)room { - (void)send:(NSString *)replyText toChatRoom:(LinphoneChatRoom *)room {
LinphoneChatMessage *msg = linphone_chat_room_create_message(room, replyText.UTF8String); LinphoneChatMessage *msg = linphone_chat_room_create_message(room, replyText.UTF8String);
linphone_chat_message_send(msg); linphone_chat_message_send(msg);
[ChatConversationView markAsRead:room]; [ChatConversationView markAsRead:room];
} }
/*
* If ICE is enabled, check if local network permission is given and show an alert message.
* It is indeed required for ICE to operate correctly.
* If it is not the the case, liblinphone will automatically skip ICE during the call.
* The purpose of this function is only to show the alert message.
*/
- (void) checkLocalNetworkPermission{
NSString *alertSuppressionKey = @"LocalNetworkPermissionAlertSuppression";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
LinphoneProxyConfig *defaultCfg = linphone_core_get_default_proxy_config(LC);
if (!defaultCfg) return;
LinphoneNatPolicy *natPolicy = linphone_proxy_config_get_nat_policy(defaultCfg);
if (!natPolicy || !linphone_nat_policy_ice_enabled(natPolicy))
return;
if (linphone_core_local_permission_enabled(LC)) return;
if (![defaults boolForKey: alertSuppressionKey]) {
UIAlertController *noticeView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Local network usage", nil)
message:NSLocalizedString(@"Granting the local network permission is recommended to enhance the audio & video quality. You may enable it from iOS settings.", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
UIAlertAction* ignoreForeverAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Don't show this again.", nil)
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
[defaults setBool:TRUE forKey: alertSuppressionKey];
}];
[noticeView addAction:defaultAction];
[noticeView addAction:ignoreForeverAction];
[PhoneMainView.instance presentViewController:noticeView animated:YES completion:nil];
}
}
- (void)call:(const LinphoneAddress *)iaddr { - (void)call:(const LinphoneAddress *)iaddr {
// First verify that network is available, abort otherwise. // First verify that network is available, abort otherwise.
if (!linphone_core_is_network_reachable(theLinphoneCore)) { if (!linphone_core_is_network_reachable(theLinphoneCore)) {
@ -1820,7 +1823,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; [PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
return; return;
} }
[self checkLocalNetworkPermission];
// For OutgoingCall, show CallOutgoingView // For OutgoingCall, show CallOutgoingView
[CallManager.instance startCallWithAddr:iaddr isSas:FALSE]; [CallManager.instance startCallWithAddr:iaddr isSas:FALSE];
} }
@ -1859,45 +1862,28 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
return [fullPath stringByAppendingPathComponent:file]; return [fullPath stringByAppendingPathComponent:file];
} }
+ (NSString *)imagesDirectory {
NSURL *basePath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kLinphoneMsgNotificationAppGroupId];
NSString *fullPath = [[basePath path] stringByAppendingString:@"/Library/Images/"];
if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {
NSError *error;
LOGW(@"Download path %@ does not exist, creating it.", fullPath);
if (![[NSFileManager defaultManager] createDirectoryAtPath:fullPath
withIntermediateDirectories:YES
attributes:nil
error:&error]) {
LOGE(@"Create download path directory error: %@", error.description);
}
}
return fullPath;
}
+ (NSString *)cacheDirectory { + (NSString *)cacheDirectory {
NSURL *basePath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kLinphoneMsgNotificationAppGroupId]; LinphoneFactory *factory = linphone_factory_get();
NSString *fullPath = [[basePath path] stringByAppendingString:@"/Library/Caches/"]; NSString *fullPath = [NSString stringWithUTF8String:linphone_factory_get_download_dir(factory, kLinphoneMsgNotificationAppGroupId.UTF8String)];
if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {
NSError *error;
LOGW(@"Download path %@ does not exist, creating it.", fullPath);
if (![[NSFileManager defaultManager] createDirectoryAtPath:fullPath
withIntermediateDirectories:YES
attributes:nil
error:&error]) {
LOGE(@"Create download path directory error: %@", error.description);
}
}
return fullPath; return fullPath;
} }
+ (NSString *)validFilePath:(NSString *)name { + (NSString *)getValidFile:(NSString *)name {
NSString *filePath = [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name]; // At present, downlaod_dir is .../Library/Images, but during sometimes download_dir was .../Library/Caches
NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
return filePath; return filePath;
} }
// if migration (move files of cacheDirectory to imagesDirectory) failed
return [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; NSString *objcGroupdId = [NSString stringWithCString:kLinphoneMsgNotificationAppGroupId.UTF8String encoding:[NSString defaultCStringEncoding]];
NSURL *basePath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:objcGroupdId];
NSString * fullPath = [[basePath path] stringByAppendingString:@"/Library/Caches/"];
fullPath = [fullPath stringByAppendingPathComponent:name];
if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {
[[NSFileManager defaultManager] copyItemAtPath:fullPath toPath:filePath error:nil];
}
return fullPath;
} }
+ (NSString *)oldPreferenceFile:(NSString *)file { + (NSString *)oldPreferenceFile:(NSString *)file {
@ -2214,4 +2200,36 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
_avatar = ret; _avatar = ret;
} }
#pragma mark - Conference
void conference_participant_changed(LinphoneConference *conference, const LinphoneParticipant *participant) {
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneConfStateParticipantListChanged object:nil];
}
void conference_device_changed(LinphoneConference *conference, const LinphoneParticipantDevice *participant) {
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneConfStateParticipantListChanged object:nil];
}
void linphone_iphone_conference_state_changed(LinphoneCore *lc, LinphoneConference *conf,LinphoneConferenceState state) {
if (state == LinphoneConferenceStateCreated) {
LinphoneConferenceCbs * cbs = linphone_conference_get_current_callbacks(conf);
if (!cbs) {
cbs = linphone_factory_create_conference_cbs(linphone_factory_get());
}
linphone_conference_cbs_set_participant_added(cbs, conference_participant_changed);
linphone_conference_cbs_set_participant_device_added(cbs, conference_device_changed);
linphone_conference_cbs_set_participant_device_removed(cbs, conference_device_changed);
linphone_conference_cbs_set_participant_removed(cbs, conference_participant_changed);
linphone_conference_add_callbacks(conf, cbs);
}
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNumber numberWithInt:state] forKey:@"state"];
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneConfStateChanged object:nil userInfo:dict];
}
@end @end

View file

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
@ -9,6 +12,7 @@
<connections> <connections>
<outlet property="avatarImage" destination="PjC-yS-i03" id="srY-K7-Ajk"/> <outlet property="avatarImage" destination="PjC-yS-i03" id="srY-K7-Ajk"/>
<outlet property="durationLabel" destination="Jgc-Z9-ItD" id="EGs-SW-dRc"/> <outlet property="durationLabel" destination="Jgc-Z9-ItD" id="EGs-SW-dRc"/>
<outlet property="kickButton" destination="nOf-6W-BeC" id="NR8-NM-f5V"/>
<outlet property="nameLabel" destination="63x-tV-T6U" id="rBP-rS-gbi"/> <outlet property="nameLabel" destination="63x-tV-T6U" id="rBP-rS-gbi"/>
</connections> </connections>
</placeholder> </placeholder>
@ -55,7 +59,7 @@
</connections> </connections>
</button> </button>
</subviews> </subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<nil key="simulatedStatusBarMetrics"/> <nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="490.57971014492756" y="28.794642857142854"/> <point key="canvasLocation" x="490.57971014492756" y="28.794642857142854"/>
@ -65,5 +69,8 @@
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/> <image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="conference_exit_default.png" width="55.200000762939453" height="46.400001525878906"/> <image name="conference_exit_default.png" width="55.200000762939453" height="46.400001525878906"/>
<image name="conference_exit_over.png" width="55.200000762939453" height="46.400001525878906"/> <image name="conference_exit_over.png" width="55.200000762939453" height="46.400001525878906"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources> </resources>
</document> </document>

View file

@ -19,13 +19,17 @@
#import "UIRoundedImageView.h" #import "UIRoundedImageView.h"
#import "LinphoneManager.h" #import "LinphoneManager.h"
#import "UIInterfaceStyleButton.h"
#define CONFERENCE_CELL_HEIGHT 60
@interface UICallConferenceCell : UITableViewCell @interface UICallConferenceCell : UITableViewCell
@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; @property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage;
@property(weak, nonatomic) IBOutlet UILabel *nameLabel; @property(weak, nonatomic) IBOutlet UILabel *nameLabel;
@property(weak, nonatomic) IBOutlet UILabel *durationLabel; @property(weak, nonatomic) IBOutlet UILabel *durationLabel;
@property(nonatomic, setter=setCall:) LinphoneCall *call; @property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *kickButton;
@property(nonatomic, setter=setParticipant:) LinphoneParticipant *participant;
- (id)initWithIdentifier:(NSString *)identifier; - (id)initWithIdentifier:(NSString *)identifier;
- (IBAction)onKickClick:(id)sender; - (IBAction)onKickClick:(id)sender;

View file

@ -19,6 +19,7 @@
#import "UICallConferenceCell.h" #import "UICallConferenceCell.h"
#import "Utils.h" #import "Utils.h"
#import "PhoneMainView.h"
@implementation UICallConferenceCell @implementation UICallConferenceCell
@ -38,22 +39,31 @@
return self; return self;
} }
- (void)setCall:(LinphoneCall *)call { - (void)setParticipant:(LinphoneParticipant *)p {
_call = call; _participant = p;
if (!call || !linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call))) { if (!p) {
LOGF(@"Invalid call: either NULL or not in conference."); return;
}
const LinphoneAddress *addr = linphone_participant_get_address(p);
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr];
_durationLabel.text = [LinphoneUtils durationToString:[NSDate date].timeIntervalSince1970 - linphone_participant_get_creation_time(p)];
_kickButton.hidden = CallManager.instance.isInConferenceAsGuest;
}
- (IBAction)onKickClick:(id)sender {
if (!_participant) {
return; return;
} }
const LinphoneAddress *addr = linphone_call_get_remote_address(call); if ([CallManager callKitEnabled]) {
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; LinphoneCall *call = [CallManager.instance getCallForParticipant:_participant];
if (call) {
[CallManager.instance setHeldWithCall:call hold:true];
}
}
linphone_conference_remove_participant_2([CallManager.instance getConference], _participant);
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
_durationLabel.text = [LinphoneUtils durationToString:linphone_call_get_duration(call)];
}
- (IBAction)onKickClick:(id)sender {
linphone_core_remove_from_conference(LC, _call);
} }
@end @end

View file

@ -40,7 +40,7 @@
- (void)setCall:(LinphoneCall *)call { - (void)setCall:(LinphoneCall *)call {
// if no call is provided, we assume that this is a conference // if no call is provided, we assume that this is a conference
if (!call) { if (!call || linphone_call_get_conference(call)) {
[_pauseButton setType:UIPauseButtonType_Conference call:call]; [_pauseButton setType:UIPauseButtonType_Conference call:call];
_nameLabel.text = NSLocalizedString(@"Conference", nil); _nameLabel.text = NSLocalizedString(@"Conference", nil);
[_avatarImage setImage:[UIImage imageNamed:@"options_start_conference_default.png"] [_avatarImage setImage:[UIImage imageNamed:@"options_start_conference_default.png"]

View file

@ -266,7 +266,7 @@
ms_free(cPath); ms_free(cPath);
[LinphoneManager setValueInMessageAppData:filePath forKey:@"encryptedfile" inMessage:self.message]; [LinphoneManager setValueInMessageAppData:filePath forKey:@"encryptedfile" inMessage:self.message];
} else { } else {
filePath = [LinphoneManager validFilePath:fileName]; filePath = [LinphoneManager getValidFile:fileName];
} }
} }
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
@ -435,7 +435,7 @@
if (!filePath) { if (!filePath) {
NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:self.message]; NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:self.message];
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message];
filePath = [LinphoneManager validFilePath:(localVideo?:localFile)]; filePath = [LinphoneManager getValidFile:(localVideo?:localFile)];
} }
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
@ -492,8 +492,8 @@
return; return;
} }
NSString *name = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; NSString *name = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message];
if([[NSFileManager defaultManager] fileExistsAtPath: [LinphoneManager validFilePath:name]]) { if([[NSFileManager defaultManager] fileExistsAtPath:[LinphoneManager getValidFile:name]]) {
[view openFileWithURL:[ChatConversationView getFileUrl:name]]; [view openFileWithURL:[ChatConversationView getCacheFileUrl:name]];
} else { } else {
[view openFileWithURL:[view getICloudFileUrl:name]]; [view openFileWithURL:[view getICloudFileUrl:name]];
} }
@ -540,16 +540,16 @@
NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:self.message]; NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:self.message];
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message];
NSString *imageName = NULL; NSString *imageName = NULL;
if (localImage && [[NSFileManager defaultManager] fileExistsAtPath: [LinphoneManager validFilePath:localImage]]) { if (localImage && [[NSFileManager defaultManager] fileExistsAtPath:[LinphoneManager getValidFile:localImage]]) {
imageName = localImage; imageName = localImage;
} else if (localFile && [[NSFileManager defaultManager] fileExistsAtPath:[LinphoneManager validFilePath:localFile]]) { } else if (localFile && [[NSFileManager defaultManager] fileExistsAtPath:[LinphoneManager getValidFile:localFile]]) {
if ([localFile hasSuffix:@"JPG"] || [localFile hasSuffix:@"PNG"] || [localFile hasSuffix:@"jpg"] || [localFile hasSuffix:@"png"]) { if ([localFile hasSuffix:@"JPG"] || [localFile hasSuffix:@"PNG"] || [localFile hasSuffix:@"jpg"] || [localFile hasSuffix:@"png"]) {
imageName = localFile; imageName = localFile;
} }
} }
if (imageName) { if (imageName) {
NSData *data = [NSData dataWithContentsOfFile:[LinphoneManager validFilePath:imageName]]; NSData *data = [NSData dataWithContentsOfFile:[LinphoneManager getValidFile:imageName]];
UIImage *image = [[UIImage alloc] initWithData:data]; UIImage *image = [[UIImage alloc] initWithData:data];
if (image) if (image)
[view setImage:image]; [view setImage:image];

View file

@ -75,7 +75,7 @@
for(NSString *path in [encrptedFilePaths allValues]) { for(NSString *path in [encrptedFilePaths allValues]) {
if (![path isEqualToString:@""]) { if (![path isEqualToString:@""]) {
LOGW(@"[vfs]s remove item at %@",path); LOGW(@"[vfs]s remove item at %@",path);
if ([path isEqualToString:[LinphoneManager imagesDirectory]]) { if ([path isEqualToString:[LinphoneManager cacheDirectory]]) {
LOGE(@"[vfs] something is wrong, can not delete the cache directory"); LOGE(@"[vfs] something is wrong, can not delete the cache directory");
break; break;
} }
@ -92,7 +92,7 @@
if (![filePath isEqualToString:@""]) { if (![filePath isEqualToString:@""]) {
NSError *error = nil; NSError *error = nil;
LOGW(@"[vfs] remove item at %@",filePath); LOGW(@"[vfs] remove item at %@",filePath);
if ([filePath isEqualToString:[LinphoneManager imagesDirectory]]) { if ([filePath isEqualToString:[LinphoneManager cacheDirectory]]) {
LOGE(@"[vfs] something is wrong, can not delete the cache directory"); LOGE(@"[vfs] something is wrong, can not delete the cache directory");
} else { } else {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]; [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
@ -167,7 +167,7 @@
return; return;
} }
if (_messageText && ![LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message]) { if (_messageText) {
[_messageText setHidden:FALSE]; [_messageText setHidden:FALSE];
/* We need to use an attributed string here so that data detector don't mess /* We need to use an attributed string here so that data detector don't mess
* with the text style. See http://stackoverflow.com/a/20669356 */ * with the text style. See http://stackoverflow.com/a/20669356 */
@ -327,7 +327,7 @@
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSString *filePath = [encrptedFilePaths valueForKey:name]; NSString *filePath = [encrptedFilePaths valueForKey:name];
if (filePath == NULL) { if (filePath == NULL) {
filePath = [LinphoneManager validFilePath:name]; filePath = [LinphoneManager getValidFile:name];
} }
[newfileContext addObject:[NSData dataWithContentsOfFile:filePath] name:name type:[NSString stringWithUTF8String:linphone_content_get_type(content)]]; [newfileContext addObject:[NSData dataWithContentsOfFile:filePath] name:name type:[NSString stringWithUTF8String:linphone_content_get_type(content)]];
} }
@ -354,11 +354,11 @@
const char *text = linphone_chat_message_get_text_content(_message); const char *text = linphone_chat_message_get_text_content(_message);
NSString *str = text ? [NSString stringWithUTF8String:text] : NULL; NSString *str = text ? [NSString stringWithUTF8String:text] : NULL;
if (localImage) { if (localImage) {
[_chatRoomDelegate resendFile: (data?:[ChatConversationView getFileData:localImage]) withName:localImage type:@"image" key:@"localimage" message:str]; [_chatRoomDelegate resendFile: (data?:[ChatConversationView getCacheFileData:localImage]) withName:localImage type:@"image" key:@"localimage" message:str];
} else if (localVideo) { } else if (localVideo) {
[_chatRoomDelegate resendFile:(data?:[ChatConversationView getFileData:localVideo]) withName:localVideo type:@"video" key:@"localvideo" message:str]; [_chatRoomDelegate resendFile:(data?:[ChatConversationView getCacheFileData:localVideo]) withName:localVideo type:@"video" key:@"localvideo" message:str];
} else { } else {
[_chatRoomDelegate resendFile:(data?:[ChatConversationView getFileData:localFile]) withName:localFile type:@"image" key:@"localfile" message:str]; [_chatRoomDelegate resendFile:(data?:[ChatConversationView getCacheFileData:localFile]) withName:localFile type:@"image" key:@"localfile" message:str];
} }
}); });
} else { } else {
@ -441,7 +441,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
NSString *type = [NSString stringWithUTF8String:linphone_content_get_type(content)]; NSString *type = [NSString stringWithUTF8String:linphone_content_get_type(content)];
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
if (!filePath) { if (!filePath) {
filePath = [LinphoneManager validFilePath:name]; filePath = [LinphoneManager getValidFile:name];
} }
UIImage *image = nil; UIImage *image = nil;
@ -502,7 +502,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSString *filePath=[encrptedFilePaths valueForKey:name]; NSString *filePath=[encrptedFilePaths valueForKey:name];
if (filePath == NULL) { if (filePath == NULL) {
filePath = [LinphoneManager validFilePath:name]; filePath = [LinphoneManager getValidFile:name];
} }
image = [UIChatBubbleTextCell getImageFromContent:content filePath:filePath]; image = [UIChatBubbleTextCell getImageFromContent:content filePath:filePath];
@ -562,7 +562,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
CGSize originalImageSize = CGSizeMake(230, 50); CGSize originalImageSize = CGSizeMake(230, 50);
if (!filePath) { if (!filePath) {
filePath = [LinphoneManager validFilePath:fileName]; filePath = [LinphoneManager getValidFile:fileName];
} }
if (localFile) { if (localFile) {
UIImage *image = nil; UIImage *image = nil;

View file

@ -48,7 +48,7 @@
} else { } else {
if (_filePath == NULL) { if (_filePath == NULL) {
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
_filePath = [LinphoneManager validFilePath:name]; _filePath = [LinphoneManager getValidFile:name];
} }
UIImage *image = [UIChatBubbleTextCell getImageFromContent:content filePath:_filePath]; UIImage *image = [UIChatBubbleTextCell getImageFromContent:content filePath:_filePath];
[self setImage:image]; [self setImage:image];
@ -67,7 +67,7 @@
-(IBAction)onDownloadClick:(id)sender { -(IBAction)onDownloadClick:(id)sender {
_downloadButton.enabled = NO; _downloadButton.enabled = NO;
linphone_content_set_file_path(_content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(_content)]].UTF8String); linphone_content_set_file_path(_content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(_content)]].UTF8String);
linphone_chat_message_download_content(_message, _content); linphone_chat_message_download_content(_message, _content);
} }

View file

@ -94,8 +94,7 @@
break; break;
} }
case UIPauseButtonType_Conference: { case UIPauseButtonType_Conference: {
linphone_core_leave_conference(LC); linphone_core_leave_conference(CallManager.instance.getConference);
// Fake event // Fake event
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self]; [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
break; break;
@ -132,7 +131,7 @@
break; break;
} }
case UIPauseButtonType_Conference: { case UIPauseButtonType_Conference: {
linphone_core_enter_conference(LC); linphone_core_enter_conference(CallManager.instance.getConference);
// Fake event // Fake event
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self]; [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
break; break;
@ -154,9 +153,9 @@
LinphoneCall *c = call; LinphoneCall *c = call;
switch (type) { switch (type) {
case UIPauseButtonType_Conference: { case UIPauseButtonType_Conference: {
self.enabled = (linphone_core_get_conference_size(LC) > 0); self.enabled = CallManager.instance.getConference && (linphone_conference_get_participant_count(CallManager.instance.getConference)> 0);
if (self.enabled) { if (self.enabled) {
ret = (!linphone_core_is_in_conference(LC)); ret = (!CallManager.instance.isInConference);
} }
break; break;
} }
@ -167,8 +166,8 @@
LinphoneCallState state = linphone_call_get_state(c); LinphoneCallState state = linphone_call_get_state(c);
ret = (state == LinphoneCallPaused || state == LinphoneCallPausing); ret = (state == LinphoneCallPaused || state == LinphoneCallPausing);
self.enabled = !linphone_core_sound_resources_locked(LC) && self.enabled = !linphone_core_sound_resources_locked(LC) &&
(state == LinphoneCallPaused || state == LinphoneCallPausing || (state == LinphoneCallPaused || state == LinphoneCallPausing ||
state == LinphoneCallStreamsRunning); state == LinphoneCallStreamsRunning);
} else { } else {
self.enabled = FALSE; self.enabled = FALSE;
} }

View file

@ -49,6 +49,10 @@ INIT_WITH_COMMON_CF {
linphone_call_params_enable_video(call_params, TRUE); linphone_call_params_enable_video(call_params, TRUE);
linphone_call_update(call, call_params); linphone_call_update(call, call_params);
linphone_call_params_unref(call_params); linphone_call_params_unref(call_params);
} else if (self.inAudioConf) {
LinphoneConferenceParams *cp = linphone_core_create_conference_params(LC);
linphone_conference_params_set_video_enabled(cp, true);
linphone_conference_update_params(linphone_core_get_conference(LC), cp);
} else { } else {
LOGW(@"Cannot toggle video button, because no current call"); LOGW(@"Cannot toggle video button, because no current call");
} }
@ -69,8 +73,12 @@ INIT_WITH_COMMON_CF {
linphone_call_params_enable_video(call_params, FALSE); linphone_call_params_enable_video(call_params, FALSE);
linphone_core_update_call(LC, call, call_params); linphone_core_update_call(LC, call, call_params);
linphone_call_params_unref(call_params); linphone_call_params_unref(call_params);
} else if (self.inVideoConf) {
LinphoneConferenceParams *cp = linphone_core_create_conference_params(LC);
linphone_conference_params_set_video_enabled(cp, false);
linphone_conference_update_params(linphone_core_get_conference(LC), cp);
} else { } else {
LOGW(@"Cannot toggle video button, because no current call"); LOGW(@"Cannot toggle video button, because no current call or no video conference");
} }
} }
@ -78,8 +86,8 @@ INIT_WITH_COMMON_CF {
bool video_enabled = false; bool video_enabled = false;
LinphoneCall *currentCall = linphone_core_get_current_call(LC); LinphoneCall *currentCall = linphone_core_get_current_call(LC);
if (linphone_core_video_supported(LC)) { if (linphone_core_video_supported(LC)) {
if (linphone_core_video_display_enabled(LC) && currentCall && !linphone_core_sound_resources_locked(LC) && if (self.inAudioConf || self.inVideoConf || (linphone_core_video_display_enabled(LC) && currentCall && !linphone_core_sound_resources_locked(LC) &&
linphone_call_get_state(currentCall) == LinphoneCallStreamsRunning) { linphone_call_get_state(currentCall) == LinphoneCallStreamsRunning)){
video_enabled = TRUE; video_enabled = TRUE;
} }
} }
@ -88,11 +96,19 @@ INIT_WITH_COMMON_CF {
if (last_update_state != video_enabled) if (last_update_state != video_enabled)
[waitView stopAnimating]; [waitView stopAnimating];
if (video_enabled) { if (video_enabled) {
video_enabled = linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall)); video_enabled = self.inVideoConf || (currentCall && linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall)));
} }
last_update_state = video_enabled; last_update_state = video_enabled;
return video_enabled; return video_enabled;
} }
-(BOOL) inVideoConf {
return (linphone_core_is_in_conference(LC) && linphone_core_get_conference(LC) != nil && linphone_conference_params_is_video_enabled(linphone_conference_get_current_params(linphone_core_get_conference(LC))));
}
-(BOOL) inAudioConf {
return (linphone_core_is_in_conference(LC) && linphone_core_get_conference(LC) != nil && !linphone_conference_params_is_video_enabled(linphone_conference_get_current_params(linphone_core_get_conference(LC))));
}
@end @end

View file

@ -403,7 +403,7 @@ static RootViewManager *rootViewManagerInstance = nil;
} }
case LinphoneCallEnd: { case LinphoneCallEnd: {
const MSList *calls = linphone_core_get_calls(LC); const MSList *calls = linphone_core_get_calls(LC);
if (!calls) { if (!calls || calls->data == call) {
while ((currentView == CallView.compositeViewDescription) || while ((currentView == CallView.compositeViewDescription) ||
(currentView == CallIncomingView.compositeViewDescription) || (currentView == CallIncomingView.compositeViewDescription) ||
(currentView == CallOutgoingView.compositeViewDescription)) { (currentView == CallOutgoingView.compositeViewDescription)) {

View file

@ -71,7 +71,7 @@ class ProviderDelegate: NSObject {
providerConfiguration.supportedHandleTypes = [.generic, .phoneNumber, .emailAddress] providerConfiguration.supportedHandleTypes = [.generic, .phoneNumber, .emailAddress]
providerConfiguration.maximumCallsPerCallGroup = 10 providerConfiguration.maximumCallsPerCallGroup = 10
providerConfiguration.maximumCallGroups = 2 providerConfiguration.maximumCallGroups = 10
//not show app's calls in tel's history //not show app's calls in tel's history
//providerConfiguration.includesCallsInRecents = YES; //providerConfiguration.includesCallsInRecents = YES;
@ -199,7 +199,7 @@ extension ProviderDelegate: CXProviderDelegate {
} }
do { do {
if (call?.conference != nil && action.isOnHold) { if (CallManager.instance().lc?.isInConference ?? false && action.isOnHold) {
try CallManager.instance().lc?.leaveConference() try CallManager.instance().lc?.leaveConference()
Log.directLog(BCTBX_LOG_DEBUG, text: "CallKit: call-id: [\(String(describing: callId))] leaving conference") Log.directLog(BCTBX_LOG_DEBUG, text: "CallKit: call-id: [\(String(describing: callId))] leaving conference")
NotificationCenter.default.post(name: Notification.Name("LinphoneCallUpdate"), object: self) NotificationCenter.default.post(name: Notification.Name("LinphoneCallUpdate"), object: self)
@ -215,7 +215,7 @@ extension ProviderDelegate: CXProviderDelegate {
CallManager.instance().speakerBeforePause = CallManager.instance().isSpeakerEnabled() CallManager.instance().speakerBeforePause = CallManager.instance().isSpeakerEnabled()
try call!.pause() try call!.pause()
} else { } else {
if (call?.conference != nil && CallManager.instance().lc?.callsNb ?? 0 > 1) { if (CallManager.instance().lc?.conference != nil && CallManager.instance().lc?.callsNb ?? 0 > 1) {
try CallManager.instance().lc?.enterConference() try CallManager.instance().lc?.enterConference()
NotificationCenter.default.post(name: Notification.Name("LinphoneCallUpdate"), object: self) NotificationCenter.default.post(name: Notification.Name("LinphoneCallUpdate"), object: self)
} else { } else {
@ -256,11 +256,7 @@ extension ProviderDelegate: CXProviderDelegate {
func provider(_ provider: CXProvider, perform action: CXSetGroupCallAction) { func provider(_ provider: CXProvider, perform action: CXSetGroupCallAction) {
Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: Call grouped callUUid : \(action.callUUID) with callUUID: \(String(describing: action.callUUIDToGroupWith)).") Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: Call grouped callUUid : \(action.callUUID) with callUUID: \(String(describing: action.callUUIDToGroupWith)).")
do { CallManager.instance().addAllToConference()
try CallManager.instance().lc?.addAllToConference()
} catch {
Log.directLog(BCTBX_LOG_ERROR, text: "CallKit: Call grouped failed because \(error)")
}
action.fulfill() action.fulfill()
} }

View file

@ -65,7 +65,8 @@
changeCurrentView:AssistantView.compositeViewDescription]; changeCurrentView:AssistantView.compositeViewDescription];
}]]; }]];
BOOL mustLink = ([LinphoneManager.instance lpConfigIntForKey:@"must_link_account_time"] > 0); BOOL mustLink = ([LinphoneManager.instance lpConfigIntForKey:@"must_link_account_time"] > 0);
if (mustLink) { BOOL hasAccount = linphone_core_get_account_list(LC) != NULL;
if (mustLink && hasAccount) {
[_sideMenuEntries [_sideMenuEntries
addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Link my account", nil) addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Link my account", nil)
image:[UIImage imageNamed:@"menu_link_account.png"] image:[UIImage imageNamed:@"menu_link_account.png"]

View file

@ -108,13 +108,13 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
return; return;
} }
[LinphoneManager.instance.fileTransferDelegates addObject:self]; [LinphoneManager.instance.fileTransferDelegates addObject:self];
[ChatConversationView writeFileInImagesDirectory:data name:name]; [ChatConversationView writeFileInCache:data name:name];
LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(chatRoom)); LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(chatRoom));
linphone_content_set_type(content, [type UTF8String]); linphone_content_set_type(content, [type UTF8String]);
linphone_content_set_subtype(content, [subtype UTF8String]); linphone_content_set_subtype(content, [subtype UTF8String]);
linphone_content_set_name(content, [name UTF8String]); linphone_content_set_name(content, [name UTF8String]);
linphone_content_set_file_path(content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name].UTF8String); linphone_content_set_file_path(content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name].UTF8String);
_message = linphone_chat_room_create_file_transfer_message(chatRoom, content); _message = linphone_chat_room_create_file_transfer_message(chatRoom, content);
BOOL isOneToOneChat = linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesOneToOne; BOOL isOneToOneChat = linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesOneToOne;
if (!isOneToOneChat && (_text!=nil && ![_text isEqualToString:@""])) if (!isOneToOneChat && (_text!=nil && ![_text isEqualToString:@""]))
@ -143,13 +143,13 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
NSString *name = [context.namesArray objectAtIndex:i]; NSString *name = [context.namesArray objectAtIndex:i];
NSData *data = [context.datasArray objectAtIndex:i]; NSData *data = [context.datasArray objectAtIndex:i];
[ChatConversationView writeFileInImagesDirectory:data name:name]; [ChatConversationView writeFileInCache:data name:name];
linphone_content_set_type(content, [type UTF8String]); linphone_content_set_type(content, [type UTF8String]);
linphone_content_set_subtype(content, [name.pathExtension UTF8String]); linphone_content_set_subtype(content, [name.pathExtension UTF8String]);
linphone_content_set_name(content, [name UTF8String]); linphone_content_set_name(content, [name UTF8String]);
linphone_content_set_file_path(content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name].UTF8String); linphone_content_set_file_path(content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name].UTF8String);
[names addObject:name]; [names addObject:name];
[types addObject:type]; [types addObject:type];
linphone_chat_message_add_file_content(_message, content); linphone_chat_message_add_file_content(_message, content);
@ -179,7 +179,7 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
} }
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name { - (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name {
NSURL *url = [ChatConversationView getFileUrl:name]; NSURL *url = [ChatConversationView getCacheFileUrl:name];
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
NSString *fileType = [[asset tracksWithMediaType:AVMediaTypeVideo] count] > 0 ? @"video" : @"file"; NSString *fileType = [[asset tracksWithMediaType:AVMediaTypeVideo] count] > 0 ? @"video" : @"file";
NSString *key = [ChatConversationView getKeyFromFileType:fileType fileName:name]; NSString *key = [ChatConversationView getKeyFromFileType:fileType fileName:name];
@ -202,7 +202,7 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
LOGI(@"%p Downloading content in %p ", self, message); LOGI(@"%p Downloading content in %p ", self, message);
linphone_chat_message_cbs_set_file_transfer_progress_indication(linphone_chat_message_get_callbacks(_message), file_transfer_progress_indication_recv); linphone_chat_message_cbs_set_file_transfer_progress_indication(linphone_chat_message_get_callbacks(_message), file_transfer_progress_indication_recv);
linphone_content_set_file_path(content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(content)]].UTF8String); linphone_content_set_file_path(content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(content)]].UTF8String);
linphone_chat_message_download_content(_message, content); linphone_chat_message_download_content(_message, content);
return TRUE; return TRUE;

View file

@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
def all_pods def all_pods
if ENV['PODFILE_PATH'].nil? if ENV['PODFILE_PATH'].nil?
pod 'linphone-sdk', '~> 5.0.0-alpha' pod 'linphone-sdk', '~> 5.0.63'
else else
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
end end

View file

@ -110,6 +110,8 @@
<string>Add tranfered files to your library</string> <string>Add tranfered files to your library</string>
<key>NSPhotoLibraryUsageDescription</key> <key>NSPhotoLibraryUsageDescription</key>
<string>Share photos with your friends and customize avatars</string> <string>Share photos with your friends and customize avatars</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Stream audio and video through the local network</string>
<key>NSUbiquitousContainers</key> <key>NSUbiquitousContainers</key>
<dict> <dict>
<key>iCloud.org.linphone.phone</key> <key>iCloud.org.linphone.phone</key>

View file

@ -109,7 +109,7 @@
61AE364F20C00B370089D9D3 /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AE364E20C00B370089D9D3 /* ShareViewController.m */; }; 61AE364F20C00B370089D9D3 /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AE364E20C00B370089D9D3 /* ShareViewController.m */; };
61AE365220C00B370089D9D3 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61AE365020C00B370089D9D3 /* MainInterface.storyboard */; }; 61AE365220C00B370089D9D3 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61AE365020C00B370089D9D3 /* MainInterface.storyboard */; };
61AE365620C00B370089D9D3 /* linphoneExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 61AE364B20C00B370089D9D3 /* linphoneExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 61AE365620C00B370089D9D3 /* linphoneExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 61AE364B20C00B370089D9D3 /* linphoneExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
61AEBEA321906AFC00F35E7F /* (null) in Frameworks */ = {isa = PBXBuildFile; }; 61AEBEA321906AFC00F35E7F /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
61AEBEBD2191990A00F35E7F /* DevicesListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AEBEBC2191990A00F35E7F /* DevicesListView.m */; }; 61AEBEBD2191990A00F35E7F /* DevicesListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AEBEBC2191990A00F35E7F /* DevicesListView.m */; };
61AEBEBF2191991F00F35E7F /* DevicesListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEBE2191991F00F35E7F /* DevicesListView.xib */; }; 61AEBEBF2191991F00F35E7F /* DevicesListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEBE2191991F00F35E7F /* DevicesListView.xib */; };
61AEBEC62191E47500F35E7F /* chevron_list_close.png in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEC52191E47500F35E7F /* chevron_list_close.png */; }; 61AEBEC62191E47500F35E7F /* chevron_list_close.png in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEC52191E47500F35E7F /* chevron_list_close.png */; };
@ -622,7 +622,7 @@
63E27A321C4FECD000D332AE /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63E27A311C4FECD000D332AE /* LaunchScreen.xib */; }; 63E27A321C4FECD000D332AE /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63E27A311C4FECD000D332AE /* LaunchScreen.xib */; };
63E27A521C50EDB000D332AE /* hold.mkv in Resources */ = {isa = PBXBuildFile; fileRef = 63E27A511C50EB2700D332AE /* hold.mkv */; }; 63E27A521C50EDB000D332AE /* hold.mkv in Resources */ = {isa = PBXBuildFile; fileRef = 63E27A511C50EB2700D332AE /* hold.mkv */; };
63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */; }; 63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */; };
63E802DB1C625AEF000D5509 /* (null) in Resources */ = {isa = PBXBuildFile; }; 63E802DB1C625AEF000D5509 /* BuildFile in Resources */ = {isa = PBXBuildFile; };
63EC8D391D7438660066547B /* AssistantLinkView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63EC8D3B1D7438660066547B /* AssistantLinkView.xib */; }; 63EC8D391D7438660066547B /* AssistantLinkView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63EC8D3B1D7438660066547B /* AssistantLinkView.xib */; };
63F1DF441BCE618E00EDED90 /* UIAddressTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */; }; 63F1DF441BCE618E00EDED90 /* UIAddressTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */; };
63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF4A1BCE983200EDED90 /* CallConferenceTableView.m */; }; 63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF4A1BCE983200EDED90 /* CallConferenceTableView.m */; };
@ -1951,7 +1951,7 @@
files = ( files = (
61DD7E1F2372E88F001BDD01 /* CoreLocation.framework in Frameworks */, 61DD7E1F2372E88F001BDD01 /* CoreLocation.framework in Frameworks */,
6180D6FE21EE41A800AD9CB6 /* QuickLook.framework in Frameworks */, 6180D6FE21EE41A800AD9CB6 /* QuickLook.framework in Frameworks */,
61AEBEA321906AFC00F35E7F /* (null) in Frameworks */, 61AEBEA321906AFC00F35E7F /* BuildFile in Frameworks */,
D37DC7181594AF3400B2A5EB /* MessageUI.framework in Frameworks */, D37DC7181594AF3400B2A5EB /* MessageUI.framework in Frameworks */,
61F1997520C6B1D5006B069A /* AVKit.framework in Frameworks */, 61F1997520C6B1D5006B069A /* AVKit.framework in Frameworks */,
249660951FD6A35F001D55AA /* Photos.framework in Frameworks */, 249660951FD6A35F001D55AA /* Photos.framework in Frameworks */,
@ -2285,7 +2285,7 @@
path = LinphoneUI; path = LinphoneUI;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { 29B97314FDCFA39411CA2CEA = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
8C23BCB71D82AAC3005F19BB /* linphone.entitlements */, 8C23BCB71D82AAC3005F19BB /* linphone.entitlements */,
@ -3357,7 +3357,7 @@
fr, fr,
hu, hu,
); );
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; mainGroup = 29B97314FDCFA39411CA2CEA;
productRefGroup = 19C28FACFE9D520D11CA2CBB /* Products */; productRefGroup = 19C28FACFE9D520D11CA2CBB /* Products */;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
@ -3418,7 +3418,7 @@
633FEED41D3CD55A0014B822 /* numpad_7_default@2x.png in Resources */, 633FEED41D3CD55A0014B822 /* numpad_7_default@2x.png in Resources */,
633FEEE01D3CD55A0014B822 /* numpad_8_over~ipad@2x.png in Resources */, 633FEEE01D3CD55A0014B822 /* numpad_8_over~ipad@2x.png in Resources */,
633FEDDC1D3CD5590014B822 /* call_start_body_disabled~ipad.png in Resources */, 633FEDDC1D3CD5590014B822 /* call_start_body_disabled~ipad.png in Resources */,
63E802DB1C625AEF000D5509 /* (null) in Resources */, 63E802DB1C625AEF000D5509 /* BuildFile in Resources */,
633FEE2E1D3CD5590014B822 /* color_F.png in Resources */, 633FEE2E1D3CD5590014B822 /* color_F.png in Resources */,
633FEDC51D3CD5590014B822 /* call_hangup_disabled@2x.png in Resources */, 633FEDC51D3CD5590014B822 /* call_hangup_disabled@2x.png in Resources */,
633FEEDF1D3CD55A0014B822 /* numpad_8_over~ipad.png in Resources */, 633FEEDF1D3CD55A0014B822 /* numpad_8_over~ipad.png in Resources */,
@ -4913,7 +4913,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMPRESS_PNG_FILES = NO; COMPRESS_PNG_FILES = NO;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -4942,14 +4942,14 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
LINK_WITH_STANDARD_LIBRARIES = YES; LINK_WITH_STANDARD_LIBRARIES = YES;
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
OTHER_CFLAGS = ( OTHER_CFLAGS = (
"-DBCTBX_LOG_DOMAIN=\\\"ios\\\"", "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"",
"-DCHECK_VERSION_UPDATE=FALSE", "-DCHECK_VERSION_UPDATE=FALSE",
"-DENABLE_QRCODE=TRUE", "-DENABLE_QRCODE=TRUE",
"-DENABLE_SMS_INVITE=TRUE", "-DENABLE_SMS_INVITE=TRUE",
"$(inherited)", "$(inherited)",
"-DLINPHONE_SDK_VERSION=\\\"5.0.0-alpha.109+40dd0cf\\\"", "-DLINPHONE_SDK_VERSION=\\\"5.0.33-pre.2+607391a\\\"",
); );
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
@ -5039,7 +5039,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMPRESS_PNG_FILES = NO; COMPRESS_PNG_FILES = NO;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5065,14 +5065,14 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
LINK_WITH_STANDARD_LIBRARIES = YES; LINK_WITH_STANDARD_LIBRARIES = YES;
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
OTHER_CFLAGS = ( OTHER_CFLAGS = (
"-DBCTBX_LOG_DOMAIN=\\\"ios\\\"", "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"",
"-DCHECK_VERSION_UPDATE=FALSE", "-DCHECK_VERSION_UPDATE=FALSE",
"-DENABLE_QRCODE=TRUE", "-DENABLE_QRCODE=TRUE",
"-DENABLE_SMS_INVITE=TRUE", "-DENABLE_SMS_INVITE=TRUE",
"$(inherited)", "$(inherited)",
"-DLINPHONE_SDK_VERSION=\\\"5.0.0-alpha.109+40dd0cf\\\"", "-DLINPHONE_SDK_VERSION=\\\"5.0.33-pre.2+607391a\\\"",
); );
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
@ -5161,7 +5161,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMPRESS_PNG_FILES = NO; COMPRESS_PNG_FILES = NO;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5187,14 +5187,14 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
LINK_WITH_STANDARD_LIBRARIES = YES; LINK_WITH_STANDARD_LIBRARIES = YES;
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
OTHER_CFLAGS = ( OTHER_CFLAGS = (
"-DBCTBX_LOG_DOMAIN=\\\"ios\\\"", "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"",
"-DCHECK_VERSION_UPDATE=FALSE", "-DCHECK_VERSION_UPDATE=FALSE",
"-DENABLE_QRCODE=TRUE", "-DENABLE_QRCODE=TRUE",
"-DENABLE_SMS_INVITE=TRUE", "-DENABLE_SMS_INVITE=TRUE",
"$(inherited)", "$(inherited)",
"-DLINPHONE_SDK_VERSION=\\\"5.0.0-alpha.109+40dd0cf\\\"", "-DLINPHONE_SDK_VERSION=\\\"5.0.33-pre.2+607391a\\\"",
); );
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
@ -5282,7 +5282,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMPRESS_PNG_FILES = NO; COMPRESS_PNG_FILES = NO;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5308,14 +5308,14 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)";
LINK_WITH_STANDARD_LIBRARIES = YES; LINK_WITH_STANDARD_LIBRARIES = YES;
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
OTHER_CFLAGS = ( OTHER_CFLAGS = (
"-DBCTBX_LOG_DOMAIN=\\\"ios\\\"", "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"",
"-DCHECK_VERSION_UPDATE=FALSE", "-DCHECK_VERSION_UPDATE=FALSE",
"-DENABLE_QRCODE=TRUE", "-DENABLE_QRCODE=TRUE",
"-DENABLE_SMS_INVITE=TRUE", "-DENABLE_SMS_INVITE=TRUE",
"$(inherited)", "$(inherited)",
"-DLINPHONE_SDK_VERSION=\\\"5.0.0-alpha.109+40dd0cf\\\"", "-DLINPHONE_SDK_VERSION=\\\"5.0.33-pre.2+607391a\\\"",
); );
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone;
@ -5340,6 +5340,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -5355,7 +5356,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5367,7 +5368,7 @@
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
INFOPLIST_FILE = linphoneExtension/Info.plist; INFOPLIST_FILE = linphoneExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -5382,6 +5383,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -5397,7 +5399,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5408,7 +5410,7 @@
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
INFOPLIST_FILE = linphoneExtension/Info.plist; INFOPLIST_FILE = linphoneExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -5423,6 +5425,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -5438,7 +5441,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5449,7 +5452,7 @@
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
INFOPLIST_FILE = linphoneExtension/Info.plist; INFOPLIST_FILE = linphoneExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -5465,6 +5468,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -5480,7 +5484,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5491,7 +5495,7 @@
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
INFOPLIST_FILE = linphoneExtension/Info.plist; INFOPLIST_FILE = linphoneExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -5574,7 +5578,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5591,7 +5595,7 @@
INFOPLIST_FILE = "$(SRCROOT)/msgNotificationService/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/msgNotificationService/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
@ -5630,7 +5634,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5643,7 +5647,7 @@
INFOPLIST_FILE = "$(SRCROOT)/msgNotificationService/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/msgNotificationService/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
@ -5682,7 +5686,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5695,7 +5699,7 @@
INFOPLIST_FILE = "$(SRCROOT)/msgNotificationService/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/msgNotificationService/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
@ -5734,7 +5738,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5747,7 +5751,7 @@
INFOPLIST_FILE = "$(SRCROOT)/msgNotificationService/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/msgNotificationService/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
@ -5767,6 +5771,7 @@
baseConfigurationReference = 8B4C43A28E90775F6FCA2CEE /* Pods-msgNotificationContent.debug.xcconfig */; baseConfigurationReference = 8B4C43A28E90775F6FCA2CEE /* Pods-msgNotificationContent.debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -5785,7 +5790,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5802,7 +5807,7 @@
INFOPLIST_FILE = msgNotificationContent/Info.plist; INFOPLIST_FILE = msgNotificationContent/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
@ -5822,6 +5827,7 @@
baseConfigurationReference = 34027665305514025971F85C /* Pods-msgNotificationContent.release.xcconfig */; baseConfigurationReference = 34027665305514025971F85C /* Pods-msgNotificationContent.release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -5840,7 +5846,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5853,7 +5859,7 @@
INFOPLIST_FILE = msgNotificationContent/Info.plist; INFOPLIST_FILE = msgNotificationContent/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
@ -5873,6 +5879,7 @@
baseConfigurationReference = E40C9A7D22675584396C0A3D /* Pods-msgNotificationContent.distribution.xcconfig */; baseConfigurationReference = E40C9A7D22675584396C0A3D /* Pods-msgNotificationContent.distribution.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -5891,7 +5898,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5904,7 +5911,7 @@
INFOPLIST_FILE = msgNotificationContent/Info.plist; INFOPLIST_FILE = msgNotificationContent/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";
@ -5924,6 +5931,7 @@
baseConfigurationReference = BAD0A9494E833034EB559687 /* Pods-msgNotificationContent.distributionadhoc.xcconfig */; baseConfigurationReference = BAD0A9494E833034EB559687 /* Pods-msgNotificationContent.distributionadhoc.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
@ -5942,7 +5950,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 37; CURRENT_PROJECT_VERSION = 4;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = Z2V957B3D6; DEVELOPMENT_TEAM = Z2V957B3D6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -5955,7 +5963,7 @@
INFOPLIST_FILE = msgNotificationContent/Info.plist; INFOPLIST_FILE = msgNotificationContent/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.4.0; MARKETING_VERSION = 4.5.1;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)";