Unverified Commit 23c1cdb1 authored by Zach Knox's avatar Zach Knox
Browse files

notifications work—still work to do but it's progress

also updated pods
parent fa006df2
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2014-2016 Hearst // Copyright (c) 2014-2018 Tristan Himmelman
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2014-2016 Hearst // Copyright (c) 2014-2018 Tristan Himmelman
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2014-2016 Hearst // Copyright (c) 2014-2018 Tristan Himmelman
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -32,23 +32,43 @@ open class DateTransform: TransformType { ...@@ -32,23 +32,43 @@ open class DateTransform: TransformType {
public typealias Object = Date public typealias Object = Date
public typealias JSON = Double public typealias JSON = Double
public init() {} public enum Unit: TimeInterval {
case seconds = 1
case milliseconds = 1_000
func addScale(to interval: TimeInterval) -> TimeInterval {
return interval * rawValue
}
func removeScale(from interval: TimeInterval) -> TimeInterval {
return interval / rawValue
}
}
private let unit: Unit
public init(unit: Unit = .seconds) {
self.unit = unit
}
open func transformFromJSON(_ value: Any?) -> Date? { open func transformFromJSON(_ value: Any?) -> Date? {
var timeInterval: TimeInterval?
if let timeInt = value as? Double { if let timeInt = value as? Double {
return Date(timeIntervalSince1970: TimeInterval(timeInt)) timeInterval = TimeInterval(timeInt)
} }
if let timeStr = value as? String { if let timeStr = value as? String {
return Date(timeIntervalSince1970: TimeInterval(atof(timeStr))) timeInterval = TimeInterval(atof(timeStr))
} }
return nil return timeInterval.flatMap {
return Date(timeIntervalSince1970: unit.removeScale(from: $0))
}
} }
open func transformToJSON(_ value: Date?) -> Double? { open func transformToJSON(_ value: Date?) -> Double? {
if let date = value { if let date = value {
return Double(date.timeIntervalSince1970) return Double(unit.addScale(to: date.timeIntervalSince1970))
} }
return nil return nil
} }
......
...@@ -3,8 +3,26 @@ ...@@ -3,8 +3,26 @@
// ObjectMapper // ObjectMapper
// //
// Created by Milen Halachev on 7/20/16. // Created by Milen Halachev on 7/20/16.
// Copyright © 2016 hearst. All rights reserved.
// //
// Copyright (c) 2014-2018 Tristan Himmelman
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation import Foundation
......
...@@ -3,8 +3,28 @@ ...@@ -3,8 +3,28 @@
// ObjectMapper // ObjectMapper
// //
// Created by Tristan Himmelman on 2016-09-26. // Created by Tristan Himmelman on 2016-09-26.
// Copyright © 2016 hearst. All rights reserved.
// //
// The MIT License (MIT)
//
// Copyright (c) 2014-2018 Tristan Himmelman
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation import Foundation
...@@ -31,6 +51,14 @@ public func >>> <T: RawRepresentable>(left: T?, right: Map) { ...@@ -31,6 +51,14 @@ public func >>> <T: RawRepresentable>(left: T?, right: Map) {
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Implicitly Unwrapped Optional Object of Raw Representable type
public func <- <T: RawRepresentable>(left: inout T!, right: Map) {
left <- (right, EnumTransform())
}
#endif
// MARK:- Arrays of Raw Representable type // MARK:- Arrays of Raw Representable type
/// Array of Raw Representable object /// Array of Raw Representable object
...@@ -53,6 +81,14 @@ public func >>> <T: RawRepresentable>(left: [T]?, right: Map) { ...@@ -53,6 +81,14 @@ public func >>> <T: RawRepresentable>(left: [T]?, right: Map) {
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Array of Raw Representable object
public func <- <T: RawRepresentable>(left: inout [T]!, right: Map) {
left <- (right, EnumTransform())
}
#endif
// MARK:- Dictionaries of Raw Representable type // MARK:- Dictionaries of Raw Representable type
/// Dictionary of Raw Representable object /// Dictionary of Raw Representable object
...@@ -73,3 +109,12 @@ public func <- <T: RawRepresentable>(left: inout [String: T]?, right: Map) { ...@@ -73,3 +109,12 @@ public func <- <T: RawRepresentable>(left: inout [String: T]?, right: Map) {
public func >>> <T: RawRepresentable>(left: [String: T]?, right: Map) { public func >>> <T: RawRepresentable>(left: [String: T]?, right: Map) {
left >>> (right, EnumTransform()) left >>> (right, EnumTransform())
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Dictionary of Raw Representable object
public func <- <T: RawRepresentable>(left: inout [String: T]!, right: Map) {
left <- (right, EnumTransform())
}
#endif
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2014-2016 Hearst // Copyright (c) 2014-2018 Tristan Himmelman
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2014-2016 Hearst // Copyright (c) 2014-2016 Tristan Himmelman
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -40,6 +40,14 @@ internal final class FromJSON { ...@@ -40,6 +40,14 @@ internal final class FromJSON {
field = object field = object
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Implicitly unwrapped optional basic type
class func optionalBasicType<FieldType>(_ field: inout FieldType!, object: FieldType?) {
field = object
}
#endif
/// Mappable object /// Mappable object
class func object<N: BaseMappable>(_ field: inout N, map: Map) { class func object<N: BaseMappable>(_ field: inout N, map: Map) {
if map.toObject { if map.toObject {
...@@ -59,6 +67,18 @@ internal final class FromJSON { ...@@ -59,6 +67,18 @@ internal final class FromJSON {
} }
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Implicitly unwrapped Optional Mappable Object
class func optionalObject<N: BaseMappable>(_ field: inout N!, map: Map) {
if let f = field , map.toObject && map.currentValue != nil {
field = Mapper(context: map.context).map(JSONObject: map.currentValue, toObject: f)
} else {
field = Mapper(context: map.context).map(JSONObject: map.currentValue)
}
}
#endif
/// mappable object array /// mappable object array
class func objectArray<N: BaseMappable>(_ field: inout Array<N>, map: Map) { class func objectArray<N: BaseMappable>(_ field: inout Array<N>, map: Map) {
if let objects = Mapper<N>(context: map.context).mapArray(JSONObject: map.currentValue) { if let objects = Mapper<N>(context: map.context).mapArray(JSONObject: map.currentValue) {
...@@ -76,6 +96,18 @@ internal final class FromJSON { ...@@ -76,6 +96,18 @@ internal final class FromJSON {
} }
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Implicitly unwrapped optional mappable object array
class func optionalObjectArray<N: BaseMappable>(_ field: inout Array<N>!, map: Map) {
if let objects: Array<N> = Mapper(context: map.context).mapArray(JSONObject: map.currentValue) {
field = objects
} else {
field = nil
}
}
#endif
/// mappable object array /// mappable object array
class func twoDimensionalObjectArray<N: BaseMappable>(_ field: inout Array<Array<N>>, map: Map) { class func twoDimensionalObjectArray<N: BaseMappable>(_ field: inout Array<Array<N>>, map: Map) {
if let objects = Mapper<N>(context: map.context).mapArrayOfArrays(JSONObject: map.currentValue) { if let objects = Mapper<N>(context: map.context).mapArrayOfArrays(JSONObject: map.currentValue) {
...@@ -88,6 +120,14 @@ internal final class FromJSON { ...@@ -88,6 +120,14 @@ internal final class FromJSON {
field = Mapper(context: map.context).mapArrayOfArrays(JSONObject: map.currentValue) field = Mapper(context: map.context).mapArrayOfArrays(JSONObject: map.currentValue)
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Implicitly unwrapped optional 2 dimentional mappable object array
class func optionalTwoDimensionalObjectArray<N: BaseMappable>(_ field: inout Array<Array<N>>!, map: Map) {
field = Mapper(context: map.context).mapArrayOfArrays(JSONObject: map.currentValue)
}
#endif
/// Dctionary containing Mappable objects /// Dctionary containing Mappable objects
class func objectDictionary<N: BaseMappable>(_ field: inout Dictionary<String, N>, map: Map) { class func objectDictionary<N: BaseMappable>(_ field: inout Dictionary<String, N>, map: Map) {
if map.toObject { if map.toObject {
...@@ -108,6 +148,18 @@ internal final class FromJSON { ...@@ -108,6 +148,18 @@ internal final class FromJSON {
} }
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Implicitly unwrapped Dictionary containing Mappable objects
class func optionalObjectDictionary<N: BaseMappable>(_ field: inout Dictionary<String, N>!, map: Map) {
if let f = field , map.toObject && map.currentValue != nil {
field = Mapper(context: map.context).mapDictionary(JSONObject: map.currentValue, toDictionary: f)
} else {
field = Mapper(context: map.context).mapDictionary(JSONObject: map.currentValue)
}
}
#endif
/// Dictionary containing Array of Mappable objects /// Dictionary containing Array of Mappable objects
class func objectDictionaryOfArrays<N: BaseMappable>(_ field: inout Dictionary<String, [N]>, map: Map) { class func objectDictionaryOfArrays<N: BaseMappable>(_ field: inout Dictionary<String, [N]>, map: Map) {
if let objects = Mapper<N>(context: map.context).mapDictionaryOfArrays(JSONObject: map.currentValue) { if let objects = Mapper<N>(context: map.context).mapDictionaryOfArrays(JSONObject: map.currentValue) {
...@@ -120,6 +172,14 @@ internal final class FromJSON { ...@@ -120,6 +172,14 @@ internal final class FromJSON {
field = Mapper<N>(context: map.context).mapDictionaryOfArrays(JSONObject: map.currentValue) field = Mapper<N>(context: map.context).mapDictionaryOfArrays(JSONObject: map.currentValue)
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Implicitly unwrapped Dictionary containing Array of Mappable objects
class func optionalObjectDictionaryOfArrays<N: BaseMappable>(_ field: inout Dictionary<String, [N]>!, map: Map) {
field = Mapper<N>(context: map.context).mapDictionaryOfArrays(JSONObject: map.currentValue)
}
#endif
/// mappable object Set /// mappable object Set
class func objectSet<N: BaseMappable>(_ field: inout Set<N>, map: Map) { class func objectSet<N: BaseMappable>(_ field: inout Set<N>, map: Map) {
if let objects = Mapper<N>(context: map.context).mapSet(JSONObject: map.currentValue) { if let objects = Mapper<N>(context: map.context).mapSet(JSONObject: map.currentValue) {
...@@ -131,4 +191,12 @@ internal final class FromJSON { ...@@ -131,4 +191,12 @@ internal final class FromJSON {
class func optionalObjectSet<N: BaseMappable>(_ field: inout Set<N>?, map: Map) { class func optionalObjectSet<N: BaseMappable>(_ field: inout Set<N>?, map: Map) {
field = Mapper(context: map.context).mapSet(JSONObject: map.currentValue) field = Mapper(context: map.context).mapSet(JSONObject: map.currentValue)
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// Implicitly unwrapped optional mappable object array
class func optionalObjectSet<N: BaseMappable>(_ field: inout Set<N>!, map: Map) {
field = Mapper(context: map.context).mapSet(JSONObject: map.currentValue)
}
#endif
} }
...@@ -3,8 +3,26 @@ ...@@ -3,8 +3,26 @@
// ObjectMapper // ObjectMapper
// //
// Created by Vitaliy Kuzmenko on 10/10/16. // Created by Vitaliy Kuzmenko on 10/10/16.
// Copyright © 2016 hearst. All rights reserved.
// //
// Copyright (c) 2014-2018 Tristan Himmelman
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if os(iOS) || os(tvOS) || os(watchOS) #if os(iOS) || os(tvOS) || os(watchOS)
import UIKit import UIKit
...@@ -119,7 +137,7 @@ open class HexColorTransform: TransformType { ...@@ -119,7 +137,7 @@ open class HexColorTransform: TransformType {
#if os(iOS) || os(tvOS) || os(watchOS) #if os(iOS) || os(tvOS) || os(watchOS)
return UIColor(red: red, green: green, blue: blue, alpha: alpha) return UIColor(red: red, green: green, blue: blue, alpha: alpha)
#else #else
return NSColor(calibratedRed: red, green: green, blue: blue, alpha: alpha) return NSColor(red: red, green: green, blue: blue, alpha: alpha)
#endif #endif
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2014-2016 Hearst // Copyright (c) 2014-2018 Tristan Himmelman
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2014-2016 Hearst // Copyright (c) 2014-2018 Tristan Himmelman
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -214,7 +214,11 @@ public extension Mapper where N: ImmutableMappable { ...@@ -214,7 +214,11 @@ public extension Mapper where N: ImmutableMappable {
// MARK: Array mapping functions // MARK: Array mapping functions
public func mapArray(JSONArray: [[String: Any]]) throws -> [N] { public func mapArray(JSONArray: [[String: Any]]) throws -> [N] {
#if swift(>=4.1)
return try JSONArray.compactMap(mapOrFail) return try JSONArray.compactMap(mapOrFail)
#else
return try JSONArray.flatMap(mapOrFail)
#endif
} }
public func mapArray(JSONString: String) throws -> [N] { public func mapArray(JSONString: String) throws -> [N] {
......
...@@ -3,8 +3,28 @@ ...@@ -3,8 +3,28 @@
// ObjectMapper // ObjectMapper
// //
// Created by Suyeol Jeon on 17/02/2017. // Created by Suyeol Jeon on 17/02/2017.
// Copyright © 2017 hearst. All rights reserved.
// //
// The MIT License (MIT)
//
// Copyright (c) 2014-2018 Tristan Himmelman
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation import Foundation
...@@ -34,6 +54,21 @@ public func <- <T: SignedInteger>(left: inout T?, right: Map) { ...@@ -34,6 +54,21 @@ public func <- <T: SignedInteger>(left: inout T?, right: Map) {
} }
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// ImplicitlyUnwrappedOptional SignedInteger mapping
public func <- <T: SignedInteger>(left: inout T!, right: Map) {
switch right.mappingType {
case .fromJSON where right.isKeyPresent:
let value: T! = toSignedInteger(right.currentValue)
FromJSON.basicType(&left, object: value)
case .toJSON:
left >>> right
default: ()
}
}
#endif
// MARK: - Unsigned Integer // MARK: - Unsigned Integer
...@@ -62,6 +97,21 @@ public func <- <T: UnsignedInteger>(left: inout T?, right: Map) { ...@@ -62,6 +97,21 @@ public func <- <T: UnsignedInteger>(left: inout T?, right: Map) {
} }
} }
// Code targeting the Swift 4.1 compiler and below.
#if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
/// ImplicitlyUnwrappedOptional UnsignedInteger mapping
public func <- <T: UnsignedInteger>(left: inout T!, right: Map) {
switch right.mappingType {
case .fromJSON where right.isKeyPresent:
let value: T! = toUnsignedInteger(right.currentValue)
FromJSON.basicType(&left, object: value)
case .toJSON:
left >>> right
default: ()
}
}
#endif
// MARK: - Casting Utils // MARK: - Casting Utils
/// Convert any value to `SignedInteger`. /// Convert any value to `SignedInteger`.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2014-2016 Hearst // Copyright (c) 2014-2018 Tristan Himmelman
// //