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:
Added for new features.
Changed for changes in existing functionality.
Deprecated for once-stable features removed in upcoming releases.
Removed for deprecated features removed in this release.
Fixed for any bug fixes.
Security to invite users to upgrade in case of vulnerabilities.
Added for new features.
Changed for changes in existing functionality.
Deprecated for once-stable features removed in upcoming releases.
Removed for deprecated features removed in this release.
Fixed for any bug fixes.
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
@ -66,7 +85,7 @@ Group changes to describe their impact on the project, as follows:
### Fixed
- Automatically downloaded images are copied when shared in a chat room.
- Some UI errors from ios 13.
## [4.1.0] - 2019-05-06
### Added

View file

@ -68,7 +68,7 @@
assistant_activate_phone_number_link);
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 &&
strcmp([LinphoneManager.instance lpConfigStringForKey:@"domain_name"
inSection:@"app"

View file

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

View file

@ -21,6 +21,7 @@
#import "UICallConferenceCell.h"
#import "LinphoneManager.h"
#import "Utils.h"
#import "linphoneapp-Swift.h"
@implementation CallConferenceTableView
@ -30,21 +31,6 @@
[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
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@ -53,21 +39,16 @@
if (cell == nil) {
cell = [[UICallConferenceCell alloc] initWithIdentifier:kCellId];
}
[cell setCall:[self conferenceCallForRow:indexPath.row]];
cell.contentView.userInteractionEnabled = false;
LinphoneConference *c = [CallManager.instance getConference];
if (c != nil) {
[cell setParticipant:bctbx_list_nth_data(linphone_conference_get_participant_list(c),(int)indexPath.row)];
}
cell.contentView.userInteractionEnabled = NO;
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
const MSList *calls = linphone_core_get_calls(LC);
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;
return [CallManager.instance getConference] ? linphone_conference_get_participant_count([CallManager.instance getConference]) : 0;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

View file

@ -45,6 +45,8 @@ import AVFoundation
var endCallkit: Bool = false
var globalState : GlobalState = .Off
var actionsToPerformOnceWhenCoreIsOn : [(()->Void)] = []
var conference: Conference?
var backgroundContextCall : Call?
@objc var backgroundContextCameraIsEnabled : Bool = false
@ -137,27 +139,17 @@ import AVFoundation
}
@objc func changeRouteToSpeaker() {
for device in lc!.audioDevices {
if (device.type == AudioDeviceType.Speaker) {
lc!.outputAudioDevice = device
break
}
}
lc?.outputAudioDevice = lc?.audioDevices.first { $0.type == AudioDeviceType.Speaker }
UIDevice.current.isProximityMonitoringEnabled = false
}
@objc func changeRouteToBluetooth() {
for device in lc!.audioDevices {
if (device.type == AudioDeviceType.Bluetooth || device.type == AudioDeviceType.BluetoothA2DP) {
lc!.outputAudioDevice = device
break
}
}
lc?.outputAudioDevice = lc?.audioDevices.first { $0.type == AudioDeviceType.BluetoothA2DP || $0.type == AudioDeviceType.Bluetooth }
UIDevice.current.isProximityMonitoringEnabled = (lc!.callsNb > 0)
}
@objc func changeRouteToDefault() {
lc!.outputAudioDevice = lc!.defaultOutputAudioDevice
lc?.outputAudioDevice = lc?.defaultOutputAudioDevice
}
@objc func isBluetoothAvailable() -> Bool {
@ -266,7 +258,7 @@ import AVFoundation
}
let sAddr = Address.getSwiftObject(cObject: addr!)
if (CallManager.callKitEnabled() && !CallManager.instance().nextCallIsTransfer) {
if (CallManager.callKitEnabled() && !CallManager.instance().nextCallIsTransfer && !isInConference()) {
let uuid = UUID()
let name = FastAddressBook.displayName(for: addr) ?? "unknow"
let handle = CXHandle(type: .generic, value: sAddr.asStringUriOnly())
@ -475,6 +467,21 @@ import AVFoundation
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) {
let callLog = call.callLog
@ -626,9 +633,11 @@ import AVFoundation
}
if (cstate == .IncomingReceived || cstate == .OutgoingInit || cstate == .Connected || cstate == .StreamsRunning) {
let check = call.currentParams?.videoEnabled
if ((call.currentParams?.videoEnabled ?? false) && CallManager.instance().isReceiverEnabled()) {
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
])
}
// 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);
[_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES];
[self hideSpeaker:LinphoneManager.instance.bluetoothAvailable];
[self hideSpeaker: [CallManager.instance isBluetoothAvailable]];
[_speakerButton update];
[_microButton update];

View file

@ -24,6 +24,7 @@
#import <QuartzCore/CAAnimation.h>
#import <QuartzCore/QuartzCore.h>
#import <UserNotifications/UserNotifications.h>
#import "UICallConferenceCell.h"
#import "CallView.h"
#import "CallSideMenuView.h"
@ -147,7 +148,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[self hideRoutes:TRUE animated:FALSE];
[self hideOptions:TRUE animated:FALSE];
[self hidePad:TRUE animated:FALSE];
[self hideSpeaker:LinphoneManager.instance.bluetoothAvailable];
[self hideSpeaker: [CallManager.instance isBluetoothAvailable]];
[self callDurationUpdate];
[self onCurrentCallChange];
// Set windows (warn memory leaks)
@ -170,12 +171,25 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
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
target:self
selector:@selector(callDurationUpdate)
userInfo:nil
repeats:YES];
}
- (void)viewDidAppear:(BOOL)animated {
@ -263,7 +277,8 @@ static UICompositeViewDescription *compositeDescription = nil;
_pausedByRemoteView.hidden = NO;
[self updateInfoView:TRUE];
}
_conferenceView.hidden = !linphone_core_is_in_conference(LC);
_conferenceView.hidden = ![CallManager.instance isInConference];
[self onCurrentCallChange];
}
#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));
_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
int confSize = linphone_core_get_conference_size(LC) - (linphone_core_is_in_conference(LC) ? 1 : 0);
_optionsConferenceButton.enabled =
((linphone_core_get_calls_nb(LC) > 1) && (linphone_core_get_calls_nb(LC) != confSize));
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;
// Disable transfert in conference
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 setAnimationDuration:0.35];
_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);
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];
@ -426,12 +450,25 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[_videoWaitingForFirstImage setHidden:NO];
[_videoWaitingForFirstImage startAnimating];
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 inVideoConf])
[self hideSpinnerIndicator:nil];
else {
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 {
@ -454,15 +491,17 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
- (void)onCurrentCallChange {
LinphoneCall *call = linphone_core_get_current_call(LC);
_noActiveCallView.hidden = (call || linphone_core_is_in_conference(LC));
_callView.hidden = !call;
_conferenceView.hidden = !linphone_core_is_in_conference(LC);
_callPauseButton.hidden = !call && !linphone_core_is_in_conference(LC);
_noActiveCallView.hidden = (call || CallManager.instance.isInConference);
_callView.hidden = !call && !CallManager.instance.isInConference;
_conferenceView.hidden = !CallManager.instance.isInConference;
_conferenceView.hidden = !CallManager.instance.isInConference;
_callPauseButton.hidden = !call;
[_callPauseButton setType:UIPauseButtonType_CurrentCall call:call];
[_conferencePauseButton setType:UIPauseButtonType_Conference call:call];
if (!_callView.hidden) {
if (call) {
const LinphoneAddress *addr = linphone_call_get_remote_address(call);
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr];
char *uri = linphone_address_as_string_uri_only(addr);
@ -551,19 +590,13 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
// Update tables
[_pausedCallsTable update];
[_conferenceCallsTable update];
static LinphoneCall *currentCall = NULL;
if (!currentCall || linphone_core_get_current_call(LC) != currentCall) {
currentCall = linphone_core_get_current_call(LC);
[self onCurrentCallChange];
}
// Fake call update
if (call == NULL) {
return;
}
BOOL shouldDisableVideo = !currentCall || !linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall));
[self onCurrentCallChange];
LinphoneCall *currentCall = linphone_core_get_current_call(LC);
BOOL shouldDisableVideo = currentCall ? !linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall)): ![CallManager.instance inVideoConf];
if (videoHidden != shouldDisableVideo) {
if (!shouldDisableVideo) {
[self displayVideoCall:animated];
@ -571,12 +604,11 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[self displayAudioCall:animated];
}
}
if (!shouldDisableVideo && !linphone_core_is_in_conference(LC) && // camera is diabled duiring conference, it must be activated after leaving conference.
[UIApplication sharedApplication].applicationState == UIApplicationStateActive) { // Camera should not be enabled when in background)
linphone_call_enable_camera(call, TRUE);
}
[self updateCallView];
// Fake call update
if (call == NULL) {
return;
}
if (state != LinphoneCallPausedByRemote) {
_pausedByRemoteView.hidden = YES;
@ -623,7 +655,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max))) {
linphone_core_defer_call_update(LC, 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];
}
break;
@ -633,10 +665,12 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[self displayAudioCall:animated];
break;
case LinphoneCallPausedByRemote:
[self displayAudioCall:animated];
if (call == linphone_core_get_current_call(LC)) {
_pausedByRemoteView.hidden = NO;
[self updateInfoView:TRUE];
if (![CallManager.instance inVideoConf]) {
[self displayAudioCall:animated];
if (call == linphone_core_get_current_call(LC)) {
_pausedByRemoteView.hidden = NO;
[self updateInfoView:TRUE];
}
}
break;
case LinphoneCallEnd:
@ -651,7 +685,13 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
- (void)displayAskToEnableVideoCall:(LinphoneCall *)call {
if (linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call))) {
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 &&
!([UIApplication sharedApplication].applicationState != UIApplicationStateActive))
return;
@ -825,6 +865,9 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
}
- (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]) {
[self hideOptions:FALSE animated:ANIMATED];
} else {
@ -909,4 +952,56 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[_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

View file

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

View file

@ -901,7 +901,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
+ (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType {
NSString *filePath = [LinphoneManager validFilePath:name];
NSString *filePath = [LinphoneManager getValidFile:name];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filePath]) {
NSData* data = [NSData dataWithContentsOfFile:filePath];
@ -1324,18 +1324,18 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
[PhoneMainView.instance fullScreen:NO];
}
+ (NSData *)getFileData: (NSString *)name {
NSString *filePath = [LinphoneManager validFilePath:name];
+ (NSData *)getCacheFileData: (NSString *)name {
NSString *filePath = [LinphoneManager getValidFile:name];
return [NSData dataWithContentsOfFile:filePath];
}
+ (NSURL *)getFileUrl: (NSString *)name {
NSString *filePath = [LinphoneManager validFilePath:name];
+ (NSURL *)getCacheFileUrl: (NSString *)name {
NSString *filePath = [LinphoneManager getValidFile:name];
return [NSURL fileURLWithPath:filePath];
}
+ (void)writeFileInImagesDirectory:(NSData *)data name:(NSString *)name {
NSString *filePath = [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name];
+ (void)writeFileInCache:(NSData *)data name:(NSString *)name {
NSString *filePath =[LinphoneManager getValidFile:name];
if (name || [name isEqualToString:@""]) {
LOGW(@"try to write file in %@", filePath);
}
@ -1364,6 +1364,44 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
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 {
[_fileContext deleteContentWithUuid:uuid];
[self refreshImageDrawer];

View file

@ -202,15 +202,19 @@
[self setCString:tmp forKey:@"account_proxy_preference"];
}
const char *tname = "udp";
switch (linphone_address_get_transport(proxy_addr)) {
case LinphoneTransportTcp:
tname = "tcp";
break;
case LinphoneTransportTls:
tname = "tls";
break;
default:
break;
if (linphone_address_get_secure(proxy_addr)) {
tname = "tls";
} else {
switch (linphone_address_get_transport(proxy_addr)) {
case LinphoneTransportTcp:
tname = "tcp";
break;
case LinphoneTransportTls:
tname = "tls";
break;
default:
break;
}
}
linphone_address_unref(proxy_addr);
[self setCString:tname forKey:@"account_transport_preference"];
@ -495,6 +499,7 @@
NSString *userID = [self stringForKey:@"account_userid_preference"];
NSString *domain = [self stringForKey:@"account_mandatory_domain_preference"];
NSString *transport = [self stringForKey:@"account_transport_preference"];
BOOL isTransportTls = [transport isEqualToString:@"tls"];
NSString *accountHa1 = [self stringForKey:@"ha1_preference"];
NSString *accountPassword = [self stringForKey:@"account_mandatory_password_preference"];
NSString *accountAlgoPreference = [self stringForKey:@"ha1_algo_preference"];
@ -515,8 +520,12 @@
proxyAddress = domain;
}
if (![proxyAddress hasPrefix:@"sip:"] && ![proxyAddress hasPrefix:@"sips:"]) {
proxyAddress = [NSString stringWithFormat:@"sip:%@", proxyAddress];
if (![proxyAddress hasPrefix:@"sip:"] && ![proxyAddress hasPrefix:@"sips:"]) {
if (isTransportTls) {
proxyAddress = [NSString stringWithFormat:@"sips:%@", proxyAddress];
} else {
proxyAddress = [NSString stringWithFormat:@"sip:%@", proxyAddress];
}
}
LinphoneAddress *proxy_addr = linphone_core_interpret_url(LC, proxyAddress.UTF8String);
@ -525,7 +534,7 @@
LinphoneTransportType type = LinphoneTransportUdp;
if ([transport isEqualToString:@"tcp"])
type = LinphoneTransportTcp;
else if ([transport isEqualToString:@"tls"])
else if (isTransportTls)
type = LinphoneTransportTls;
linphone_address_set_transport(proxy_addr, type);
@ -538,8 +547,9 @@
if (account == NULL)
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);
if ([LinphoneManager.instance lpConfigBoolForKey:@"use_phone_number" inSection:@"assistant"]) {
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 kLinphoneChatCreateViewChange;
extern NSString *const kLinphoneEphemeralMessageDeletedInRoom;
extern NSString *const kLinphoneConfStateParticipantListChanged;
extern NSString *const kLinphoneConfStateChanged;
extern NSString *const kLinphoneMsgNotificationAppGroupId;
@ -132,8 +135,7 @@ typedef struct _LinphoneManagerSounds {
+ (NSString *)documentFile:(NSString *)file;
+ (NSString*)dataFile:(NSString*)file;
+ (NSString*)cacheDirectory;
+ (NSString *)imagesDirectory;
+ (NSString *)validFilePath:(NSString *)name;
+ (NSString *)getValidFile:(NSString *)name;
// migration
+ (NSString *)oldPreferenceFile:(NSString *)file;
+ (NSString *)oldDataFile:(NSString *)file;
@ -186,6 +188,8 @@ typedef struct _LinphoneManagerSounds {
- (void)setupGSMInteraction;
- (BOOL)isCTCallCenterExist;
- (void) checkLocalNetworkPermission;
@property (readonly) BOOL isTesting;
@property(readonly, strong) FastAddressBook *fastAddressBook;
@ -196,7 +200,6 @@ typedef struct _LinphoneManagerSounds {
@property (readonly) sqlite3* database;
@property (readonly) LinphoneManagerSounds sounds;
@property (readonly) NSMutableArray *logs;
@property (nonatomic, assign) BOOL bluetoothAvailable;
@property (readonly) NSString* contactSipField;
@property (readonly,copy) NSString* contactFilter;
@property (copy) void (^silentPushCompletion)(UIBackgroundFetchResult);

View file

@ -75,7 +75,8 @@ NSString *const kLinphoneFileTransferRecvUpdate = @"LinphoneFileTransferRecvUpda
NSString *const kLinphoneQRCodeFound = @"LinphoneQRCodeFound";
NSString *const kLinphoneChatCreateViewChange = @"LinphoneChatCreateViewChange";
NSString *const kLinphoneEphemeralMessageDeletedInRoom = @"LinphoneEphemeralMessageDeletedInRoom";
NSString *const kLinphoneConfStateChanged = @"kLinphoneConfStateChanged";
NSString *const kLinphoneConfStateParticipantListChanged = @"kLinphoneConfStateParticipantListChanged";
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 {
if ((self = [super init])) {
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(audioRouteChangeListenerCallback:)
name:AVAudioSessionRouteChangeNotification
object:nil];
NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"];
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 copyDefaultSettings];
[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:@"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_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_conference_state_changed(cbs, linphone_iphone_conference_state_changed);
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*/
//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
(or skipped).
@ -1437,13 +1433,6 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
linphone_core_destroy(theLinphoneCore);
LOGI(@"Destroy linphonecore %p", theLinphoneCore);
theLinphoneCore = nil;
// Post event
NSDictionary *dict =
[NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"];
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCoreUpdate
object:LinphoneManager.instance
userInfo:dict];
}
libStarted = FALSE;
[[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
}
- (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 {
if ([LinphoneManager copyFile:[LinphoneManager oldPreferenceFile:@"linphonerc"] destination:[LinphoneManager preferenceFile:@"linphonerc"] override:TRUE ignore:TRUE]) {
[NSFileManager.defaultManager
@ -1760,27 +1738,52 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
}
#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
- (void)send:(NSString *)replyText toChatRoom:(LinphoneChatRoom *)room {
- (void)send:(NSString *)replyText toChatRoom:(LinphoneChatRoom *)room {
LinphoneChatMessage *msg = linphone_chat_room_create_message(room, replyText.UTF8String);
linphone_chat_message_send(msg);
[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 {
// First verify that network is available, abort otherwise.
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];
return;
}
[self checkLocalNetworkPermission];
// For OutgoingCall, show CallOutgoingView
[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];
}
+ (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 {
NSURL *basePath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kLinphoneMsgNotificationAppGroupId];
NSString *fullPath = [[basePath path] stringByAppendingString:@"/Library/Caches/"];
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);
}
}
LinphoneFactory *factory = linphone_factory_get();
NSString *fullPath = [NSString stringWithUTF8String:linphone_factory_get_download_dir(factory, kLinphoneMsgNotificationAppGroupId.UTF8String)];
return fullPath;
}
+ (NSString *)validFilePath:(NSString *)name {
NSString *filePath = [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name];
+ (NSString *)getValidFile:(NSString *)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]) {
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 {
@ -2214,4 +2200,36 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
_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

View file

@ -1,7 +1,10 @@
<?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>
<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"/>
</dependencies>
<objects>
@ -9,6 +12,7 @@
<connections>
<outlet property="avatarImage" destination="PjC-yS-i03" id="srY-K7-Ajk"/>
<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"/>
</connections>
</placeholder>
@ -55,7 +59,7 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<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="conference_exit_default.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>
</document>

View file

@ -19,13 +19,17 @@
#import "UIRoundedImageView.h"
#import "LinphoneManager.h"
#import "UIInterfaceStyleButton.h"
#define CONFERENCE_CELL_HEIGHT 60
@interface UICallConferenceCell : UITableViewCell
@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage;
@property(weak, nonatomic) IBOutlet UILabel *nameLabel;
@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;
- (IBAction)onKickClick:(id)sender;

View file

@ -19,6 +19,7 @@
#import "UICallConferenceCell.h"
#import "Utils.h"
#import "PhoneMainView.h"
@implementation UICallConferenceCell
@ -38,22 +39,31 @@
return self;
}
- (void)setCall:(LinphoneCall *)call {
_call = call;
if (!call || !linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call))) {
LOGF(@"Invalid call: either NULL or not in conference.");
- (void)setParticipant:(LinphoneParticipant *)p {
_participant = p;
if (!p) {
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;
}
const LinphoneAddress *addr = linphone_call_get_remote_address(call);
[ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr];
if ([CallManager callKitEnabled]) {
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

View file

@ -40,7 +40,7 @@
- (void)setCall:(LinphoneCall *)call {
// 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];
_nameLabel.text = NSLocalizedString(@"Conference", nil);
[_avatarImage setImage:[UIImage imageNamed:@"options_start_conference_default.png"]

View file

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

View file

@ -75,7 +75,7 @@
for(NSString *path in [encrptedFilePaths allValues]) {
if (![path isEqualToString:@""]) {
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");
break;
}
@ -92,7 +92,7 @@
if (![filePath isEqualToString:@""]) {
NSError *error = nil;
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");
} else {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
@ -167,7 +167,7 @@
return;
}
if (_messageText && ![LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message]) {
if (_messageText) {
[_messageText setHidden:FALSE];
/* 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 */
@ -327,7 +327,7 @@
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSString *filePath = [encrptedFilePaths valueForKey:name];
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)]];
}
@ -354,11 +354,11 @@
const char *text = linphone_chat_message_get_text_content(_message);
NSString *str = text ? [NSString stringWithUTF8String:text] : NULL;
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) {
[_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 {
[_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 {
@ -441,7 +441,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
NSString *type = [NSString stringWithUTF8String:linphone_content_get_type(content)];
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
if (!filePath) {
filePath = [LinphoneManager validFilePath:name];
filePath = [LinphoneManager getValidFile:name];
}
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 *filePath=[encrptedFilePaths valueForKey:name];
if (filePath == NULL) {
filePath = [LinphoneManager validFilePath:name];
filePath = [LinphoneManager getValidFile:name];
}
image = [UIChatBubbleTextCell getImageFromContent:content filePath:filePath];
@ -562,7 +562,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
CGSize originalImageSize = CGSizeMake(230, 50);
if (!filePath) {
filePath = [LinphoneManager validFilePath:fileName];
filePath = [LinphoneManager getValidFile:fileName];
}
if (localFile) {
UIImage *image = nil;

View file

@ -48,7 +48,7 @@
} else {
if (_filePath == NULL) {
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
_filePath = [LinphoneManager validFilePath:name];
_filePath = [LinphoneManager getValidFile:name];
}
UIImage *image = [UIChatBubbleTextCell getImageFromContent:content filePath:_filePath];
[self setImage:image];
@ -67,7 +67,7 @@
-(IBAction)onDownloadClick:(id)sender {
_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);
}

View file

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

View file

@ -49,6 +49,10 @@ INIT_WITH_COMMON_CF {
linphone_call_params_enable_video(call_params, TRUE);
linphone_call_update(call, 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 {
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_core_update_call(LC, call, 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 {
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;
LinphoneCall *currentCall = linphone_core_get_current_call(LC);
if (linphone_core_video_supported(LC)) {
if (linphone_core_video_display_enabled(LC) && currentCall && !linphone_core_sound_resources_locked(LC) &&
linphone_call_get_state(currentCall) == LinphoneCallStreamsRunning) {
if (self.inAudioConf || self.inVideoConf || (linphone_core_video_display_enabled(LC) && currentCall && !linphone_core_sound_resources_locked(LC) &&
linphone_call_get_state(currentCall) == LinphoneCallStreamsRunning)){
video_enabled = TRUE;
}
}
@ -88,11 +96,19 @@ INIT_WITH_COMMON_CF {
if (last_update_state != video_enabled)
[waitView stopAnimating];
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;
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

View file

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

View file

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

View file

@ -65,7 +65,8 @@
changeCurrentView:AssistantView.compositeViewDescription];
}]];
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
addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Link my account", nil)
image:[UIImage imageNamed:@"menu_link_account.png"]

View file

@ -108,13 +108,13 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
return;
}
[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));
linphone_content_set_type(content, [type UTF8String]);
linphone_content_set_subtype(content, [subtype 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);
BOOL isOneToOneChat = linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesOneToOne;
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];
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_subtype(content, [name.pathExtension 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];
[types addObject:type];
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 {
NSURL *url = [ChatConversationView getFileUrl:name];
NSURL *url = [ChatConversationView getCacheFileUrl:name];
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
NSString *fileType = [[asset tracksWithMediaType:AVMediaTypeVideo] count] > 0 ? @"video" : @"file";
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);
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);
return TRUE;

View file

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

View file

@ -110,6 +110,8 @@
<string>Add tranfered files to your library</string>
<key>NSPhotoLibraryUsageDescription</key>
<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>
<dict>
<key>iCloud.org.linphone.phone</key>

View file

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